简体   繁体   中英

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:

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. 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). 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.

Firstly - include TableNameID in your index and not as included column, then you can specify descending in the index order.

That should speed up things regarding your 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). If it is I/O there's not much you can do because you do have to move through a lot of data.

If you'd like a very fast estimate of how many rows are in the table, try quering 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 .

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."

You didn't mention how long your indexed query is running. The index and your query look fine to me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM