我有一个包含大约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字段。
答案 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."
您没有提到索引查询的运行时间。索引和您的查询对我来说很好。