Sql Server查询性能如何?

时间:2010-02-11 15:11:20

标签: sql sql-server-2005 performance

我的联系人可以在多个群组中,但有多个请求。我需要简单地获取没有特定请求的特定组的联系人。

如何改善此查询的效果:

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)

3 个答案:

答案 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_idgroup_id先行。

此外,如果您的request_idgroup_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