我的联系人可以在多个群组中,但有多个请求。我需要简单地获取没有特定请求的特定组的联系人。
如何改善此查询的效果:
SELECT top 1 con_name ,
con_id
FROM tbl_group_to_contact gc
INNER JOIN tbl_contact c ON gc.con_id = c.id
WHERE group_id = '81'
AND NOT c.id IN ( SELECT con_id
FROM tbl_request_to_contact
WHERE request_id = '124' )
当我使用说明计划运行该查询时,它会显示此查询:
SELECT con_id
FROM tbl_request_to_contact
WHERE request_id = '124'
使用索引搜索是很昂贵的。
|--Top(TOP EXPRESSION:((1)))
|--Nested Loops(Left Anti Semi Join, OUTER REFERENCES:([c].[id]))
|--Nested Loops(Inner Join, OUTER REFERENCES:([gc].[con_id], [Expr1006]) WITH UNORDERED PREFETCH)
| |--Clustered Index Scan(OBJECT:([db_newsletter].[dbo].[tbl_group_to_contact].[PK_tbl_group_to_contact_1] AS [gc]), WHERE:([db_newsletter].[dbo].[tbl_group_to_contact].[group_id] as [gc].[group_id]=(81)) ORDERED FORWARD)
| |--Clustered Index Seek(OBJECT:([db_newsletter].[dbo].[tbl_contact].[PK_tbl_contact] AS [c]), SEEK:([c].[id]=[db_newsletter].[dbo].[tbl_group_to_contact].[con_id] as [gc].[con_id]) ORDERED FORWARD)
|--Top(TOP EXPRESSION:((1)))
|--Clustered Index Seek(OBJECT:([db_newsletter].[dbo].[tbl_request_to_contact].[PK_tbl_request_to_contact] AS [cc]), SEEK:([cc].[request_id]=(124)), WHERE:([db_newsletter].[dbo].[tbl_contact].[id] as [c].[id]=[db_newsletter].[dbo].[tbl_request_to_contact].[con_id] as [cc].[con_id]) ORDERED FORWARD)
答案 0 :(得分:2)
您的查询没问题,只需创建以下索引:
tbl_request_to_contact (request_id, con_id)
tbl_group_to_contact (group_id, con_id)
由于表似乎是链接表,因此您希望将这些组合作为主键:
ALTER TABLE tbl_request_to_contact ADD CONSTRAINT pk_rc PRIMARY KEY (request_id, con_id)
ALTER TABLE tbl_group_to_contact ADD CONSTRAINT pk_gc (group_id, con_id)
,确保request_id
和group_id
先行。
此外,如果您的request_id
和group_id
是整数,请将整数作为参数传递,而不是字符串:
SELECT con_name, con_id
FROM tbl_group_to_contact gc
JOIN tbl_contact c
ON c.id = gc.con_id
WHERE group_id = 81
AND c.id NOT IN
(
SELECT con_id
FROM tbl_request_to_contact
WHERE request_id = 124
)
,或者可能会发生隐式转换,导致索引无法使用。
<强>更新强>
根据您的计划,我发现您错过了tbl_group_to_contact
上的索引。需要全表扫描来过滤组。
创建索引:
CREATE UNIQUE INDEX ux_gc ON tbl_group_to_contact (group_id, con_id)
答案 1 :(得分:0)
您可能想尝试运行SQL Server Database Tuning Advisor。
答案 2 :(得分:0)
我同意@Quassnoi的索引。此外,您可以使用左连接仅显示没有请求的用户。这通常比子查询具有更好的性能。
request_id ='124'是什么?其他请求ID无关紧要?
SELECT con_name ,
con_id
FROM tbl_group_to_contact gc
INNER JOIN tbl_contact c ON gc.con_id = c.id
LEFT JOIN tbl_request_to_contact rtc ON gc.con_id = rtc.con_id
WHERE group_id = '81' and rtc.request_id IS NULL