[英]Improving the performance of an SQL query
I have a SQL Server table containing around 50,000,000 rows and I need to run the following two queries on it: 我有一个包含约50,000,000行的SQL Server表,我需要对其运行以下两个查询:
SELECT Count(*) AS Total
FROM TableName WITH(NOLOCK)
WHERE Col1 = 'xxx' AND Col2 = 'yyy'
then 然后
SELECT TOP 1 Col3
FROM TableName WITH(NOLOCK)
WHERE Col1 = 'xxx' AND Col2 = 'yyy'
ORDER BY TableNameId DESC
The table has the following structure: 该表具有以下结构:
dbo.TableName
TableNameId int PK
Col1 varchar(12)
Col2 varchar(256)
Col3 int
Timestamp datetime
As well as running queries on it, there are loads of inserts every second going into the table hence the NOLOCK. 除了在其上运行查询外,每秒还会有大量插入插入表中,因此会产生NOLOCK。 I've tried creating the following index:
我尝试创建以下索引:
NONCLUSTERED INDEX (Col1, Col2) INCLUDE (TableNameId, Col3)
I need these queries to return results as quick as possible (1 second max). 我需要这些查询以尽快返回结果(最大1秒)。 At this stage, I have the ability to restructure the table as the data isn't live yet, and I can also get rid of the Timestamp field if I need to.
在这个阶段,我可以重组表,因为数据还不存在,如果需要的话,我也可以摆脱Timestamp字段。
Firstly - include TableNameID
in your index and not as included column, then you can specify descending
in the index order. 首先-将
TableNameID
包含在索引中而不是包含列中,然后可以descending
索引顺序指定descending
。
That should speed up things regarding your TOP 1 ... ORDER BY TableNameId DESC
那应该加快与您的
TOP 1 ... ORDER BY TableNameId DESC
有关的事情TOP 1 ... ORDER BY TableNameId DESC
Secondly - check up on how much time is I/O for example (SET STATISTICS IO ON) and how much is CPU (SET STATISTICS TIME ON). 其次-检查例如I / O有多少时间(SET STATISTICS IO ON)和CPU有多少时间(SET STATISTICS TIME ON)。 If it is I/O there's not much you can do because you do have to move through a lot of data.
如果是I / O,那么您将无能为力,因为您必须浏览大量数据。
If you'd like a very fast estimate of how many rows are in the table, try quering sys.dm_db_partition_stats : 如果您想快速估算表中有多少行,请尝试查询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
If you have multiple partitions, this may not work. 如果您有多个分区,则可能无法正常工作。 You might need to get the
SUM
of the row_count
. 您可能需要获取
row_count
的SUM
。
However, if you need an accurate count, you will need to count the rows, and this will take a while. 但是,如果需要准确的计数,则需要对行进行计数,这将需要一段时间。 Also, you may get the error "Could not continue scan with NOLOCK due to data movement."
另外,您可能会收到错误“由于数据移动,无法继续使用NOLOCK进行扫描”。
You didn't mention how long your indexed query is running. 您没有提到索引查询运行了多长时间。 The index and your query look fine to me.
该索引和您的查询对我来说很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.