为服务器端分页查询创建适当的索引

时间:2014-03-03 15:04:48

标签: sql-server database indexing

我有以下查询:

SELECT TOP (100000) 
    [Filter1].[ID] AS [ID], 
    [Filter1].[FIELD1] AS [FIELD1], 
    [Filter1].[FIELD2] AS [FIELD2], 
    [Filter1].[FIELD3] AS [FIELD3], 
    [Filter1].[FIELD4] AS [FIELD4], 
    ...
    [Filter1].[FIELD30] AS [FIELD30], 
    FROM ( SELECT [Extent1].[ID] AS [ID],
         [Extent1].[FIELD1] AS [FIELD1],
         [Extent1].[FIELD2] AS [FIELD2],
         [Extent1].[FIELD3] AS [FIELD3]
         ...
         [Filter1].[FIELD30] AS [FIELD30], 
         row_number() OVER (ORDER BY [Extent1].[ID] ASC) AS [row_number]
         FROM [dbo].[TABLE] AS [Extent1]
         WHERE (N'VALUE1' <> [Extent1].[**FIELD2**]
         AND (N'VALUE2' <> ([Extent1].[**FIELD3**])
         AND ([Extent1].[**FIELD4**] IN (VALUE1, VALUE2, VALUE3, .... VALUE9)))
         AS [Filter1]
    WHERE [Filter1].[row_number] > 0
    ORDER BY [Filter1].[ID] ASC

由于需要选择的行数(几百万),我正在批量执行,因此row_number过滤。目前,查询分析器表示在FIELD1上进行了聚簇索引扫描。我仍然想要更好的性能,这就是为什么我尝试对WHERE和ORDER BY子句中的字段进行索引。

到目前为止我尝试过:

上的非聚集索引
FIELD2 ASC,
FIELD3 ASC,
FIELD4 ASC,
ID ASC

每一种可能的排列。查询执行时间加倍并增加三倍。

为什么会发生这种情况,我可以创建哪种索引来加快速度?

顺便说一句,我正在运行SQL Server 2005,因此无法使用过滤索引。兼容级别为7.0。

2 个答案:

答案 0 :(得分:1)

嘿,我在本地进行了一些虚拟数据测试。考虑到你现在没有任何索引,我正在提出这个建议。或者如果你有任何测试,请先放弃这个建议。

1)[FIELD1]未在任何过滤器中使用。将主键设为非聚类。

2)现在在列上创建聚簇索引(FIELD2 ASC,FIELD3 ASC,FIELD4 ASC)

3)您在[ID]列上排序了ROW_NUMBER函数。因此,在外部order by子句中使用[Row_Number]而不是[ID]

4)更改查询中的Where筛选器顺序。首先保持[FIELD4]滤波器,然后使用[FIELD2]和[FIELD3]滤波器。

5)如果列的数据类型[FIELD2]和[FIELD3]是INT / NUMERIC / DATE,那么您可以替换“&lt;&gt;”运算符与“(&gt; OR&lt; =)”的组合。

6)如果列[FIELD2]和[FIELD3]的数据类型为STRING,则将那些WHERE过滤器保留为“&lt;&gt;”操作

SQL FIDDLE上查看这些建议。这个没有任何数据,但解释了上面的索引和查询建议

根据上述建议,您将获得“Index Seek”,这应该会给您带来良好的性能提升。在我使用2M行表的虚拟数据进行测试时,它在SSMS中在2秒内返回50k行。

答案 1 :(得分:0)

此处的解决方案是忽略where和order by子句的索引,而是将order by子句更改为&#34; ORDER BY [Filter1]。[FIELD2] ASC&#34;已存在聚集索引的位置。这样,在3秒内返回100k行。文件中的排序已更改,但服务器端分页未受影响。