提高SQL查询的性能

时间:2014-05-15 13:11:44

标签: sql sql-server

我有一个包含大约50,000,000行的SQL Server表,我需要在其上运行以下两个查询:

SELECT  Count(*) AS Total
FROM    TableName WITH(NOLOCK)
WHERE   Col1 = 'xxx' AND Col2 = 'yyy'

然后

SELECT  TOP 1   Col3
FROM            TableName WITH(NOLOCK)
WHERE           Col1 = 'xxx' AND Col2 = 'yyy'
ORDER BY        TableNameId DESC

该表具有以下结构:

dbo.TableName
TableNameId  int PK
Col1         varchar(12)
Col2         varchar(256)
Col3         int
Timestamp    datetime

除了在其上运行查询之外,每秒都有大量插入进入表格,因此NOLOCK。我尝试过创建以下索引:

NONCLUSTERED INDEX (Col1, Col2) INCLUDE (TableNameId, Col3)

我需要这些查询尽可能快地返回结果(最多1秒)。在这个阶段,我有能力重组表格,因为数据尚未生效,如果需要,我还可以删除Timestamp字段。

2 个答案:

答案 0 :(得分:0)

首先 - 在索引中包含TableNameID而不是包含列,然后您可以在索引顺序中指定descending

这可以加快您TOP 1 ... ORDER BY TableNameId DESC

的速度

其次 - 检查I / O的时间长度(SET STATISTICS IO ON)和CPU(SET STATISTICS TIME ON)的数量。 如果它是I / O,你可以做的不多,因为你必须经过大量的数据。

答案 1 :(得分:0)

如果您想快速估算表中的行数,请尝试查询sys.dm_db_partition_stats

-- Report how many rows are in each table
SELECT o.name as [Table Name], ddps.row_count 
FROM sys.indexes (nolock) AS i 
 INNER JOIN sys.objects (nolock) AS o ON i.OBJECT_ID = o.OBJECT_ID 
 INNER JOIN sys.dm_db_partition_stats (nolock) AS ddps ON i.OBJECT_ID = ddps.OBJECT_ID 
 AND i.index_id = ddps.index_id 
WHERE i.index_id < 2 
 AND o.is_ms_shipped = 0   -- Remove to include system objects 
 AND ddps.row_count > 0
ORDER BY ddps.row_count DESC

如果您有多个分区,则可能无效。您可能需要获取SUM的{​​{1}}。

但是,如果您需要准确计数,则需要计算行数,这需要一段时间。此外,您可能会收到错误"Could not continue scan with NOLOCK due to data movement."

您没有提到索引查询的运行时间。索引和您的查询对我来说很好。