关于非聚集索引的Where子句与聚簇索引上的额外连接和where子句有关

时间:2010-08-04 10:14:04

标签: sql-server sql-server-2005 indexing clustered-index non-clustered-index

我试图从一些sql查询中获得额外的性能,这些查询在一个字段上有一个where子句,这是一个非唯一的非聚集索引,它也是表A中的外键。那个外键是表B上的主键是聚集索引。

我想知道的是,如果我将表A中的连接添加到表B并且在字段上使用where子句作为聚簇索引(与非聚集索引相反),我是否会获得性能提升额外的加入)?

感谢

5 个答案:

答案 0 :(得分:2)

要真正实现额外的性能,最好确保您的非唯一非聚集索引是covering index(即,索引包含所需的所有列满足您正在执行的查询的查询。您可以利用SQL 2005中引入的included columns概念来帮助您实现此目的。

答案 1 :(得分:1)

我做了一些测试。我有两个表 - tableA(~3000行)和tableB(~200行)。他们俩都有列id。 TableA:ID - pk,TableB:ID - fk,非聚集索引。

从一张桌子中选择:

SELECT 
    a.ID
FROM
    dbo.TableA a
WHERE 
    a.ID IN (1,5,7,9,23,45,56,546,67,32,54,676)

- 执行计划:

|--Index Seek(OBJECT:([Database].[dbo].[TableA].[IX_TableA_ID] AS [a]), SEEK:([a].[ID]=(1) OR [a].[ID]=(5)) ORDERED FORWARD)

- ç计IO:

Table 'TableA'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

选择使用两个表(内连接)

SELECT 
    t.ID
FROM
    dbo.TableA a
INNER JOIN 
    dbo.TableB t  with(index(PK_TableBs)) ON t.ID = a.ID
WHERE 
    t.ID IN (1,5,7,9,23,45,56,546,67,32,54,676)

- 执行计划:

  |--Nested Loops(Inner Join, OUTER REFERENCES:([t].[ID]))
       |--Clustered Index Seek(OBJECT:([Database].[dbo].[TableB].[PK_TableB] AS [t]), SEEK:([t].[ID]=(1) OR [t].[ID]=(5)) ORDERED FORWARD)
       |--Index Seek(OBJECT:([Database].[dbo].[TableA].[IX_TableA_ID] AS [a]), SEEK:([a].[ID]=[Database].[dbo].[TableB].[ID] as [t].[ID]),  WHERE:([Database].[dbo].[TableA].[ID] as [a].[ID]>=(1) AND [Database].[dbo].[TableA].[ID] as [a].[ID]<=(5)) ORDERED FORWARD)

- ç计IO:

Table 'TableA'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TableB'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

<强>结果:

第二个查询成本是第一个查询(33%)的67%(相对于批处理)。 此外,第二个查询需要更多读取。

PS。这是一个肮脏的快速示例,您应该检查自己的。

答案 2 :(得分:0)

我不这么认为,因为添加另一个表会涉及更多的读取。但你必须进行测试。

答案 3 :(得分:0)

根据Frank的说法,这需要从表B中读取更多页面。您说您已经在执行过滤的外键上有一个NC索引。您还可以考虑权衡FK(B的PK)对表A进行聚类的优缺点 - 如果您通常通过在B上过滤来获取表A,那么这可能会减少在A上获取的页数(但显然,可能存在其他可能受此影响的查询,可能会对此产生影响)

答案 4 :(得分:0)

如果你考虑联接是如何工作的 - 它将不得不在表A中搜索FK列以满足连接条件 - 这是你似乎试图避免的扫描。所以我不相信这有可能改善表现。