[英]Query Performance in SQL Server
我有一個包含超過1100萬條記錄的SQL Server表。 這些記錄按“類別”和“平台”進行組織。 我為以下情況感到困惑...
SELECT COUNT(*) FROM TableName WHERE Category = 'session' AND Platform = 'windows';
-- Returns 1261500
SELECT COUNT(*) FROM TableName WHERE Category = 'session' AND Platform = 'linux';
-- Returns 1890599
因此,與“ linux”關聯的記錄比“ windows”多出60萬多個記錄。
但是,此查詢將在6-9秒內返回...
SELECT MAX(id) FROM TableName WHERE Category = 'session' AND Platform = 'linux';
然而,我必須等待13分鍾以上才能殺死它……
SELECT MAX(id) FROM TableName WHERE Category = 'session' AND Platform = 'windows';
哦...我桌上還有以下索引...
CREATE NONCLUSTERED INDEX [IX_TableName_CategoryPlatform] ON [dbo].[TableName]
(
[Platform] ASC,
[Category] ASC,
[CreateDate] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
威士忌,探戈,狐步舞?
為什么搜索詞會有所作為,特別是因為已有索引?
我剛剛做了以下觀察...
SELECT MAX(id) FROM TableName WHERE Platform = 'windows';
通過從查詢中刪除類別 ,可以非常快速地返回響應...
我已根據要求創建了幾個執行計划。 但是,我注意到的是,“粘貼計划”實用程序生成的計划中的百分比與我在SSMS中獲得的內容似乎有所不同,因此我在每個鏈接下方包括了在“管理”中看到的百分比工作室。
對於以下查詢(有效)...
SELECT MAX([MessageID]) [MaxID] FROM [BoothComm].[UniversalMessageQueue] WHERE [MessagePlatform]='windows';
https://www.brentozar.com/pastetheplan/?id=Sk9q59CqZ
下一個查詢(不起作用)我只能提供一個ESTIMATED執行計划。
SELECT
MAX(MessageID) AS [MaxID]
FROM BoothComm.UniversalMessageQueue
WHERE
MessageCategory = 'session'
AND
MessagePlatform = 'windows'
https://www.brentozar.com/pastetheplan/?id=r1zqnq09-
(感謝所有幫助!)
因此,在下面所有的討論和更改之后,我仍然遇到問題...
為什么此查詢在1秒內返回(由於將ID添加到索引)...
SELECT
MAX(MessageID) AS [MaxID]
FROM BoothComm.UniversalMessageQueue
WHERE
MessagePlatform = 'linux'
AND
MessageCategory = 'accounting'
而這需要13 -22秒才能運行...
SELECT
MAX(MessageID) AS [MaxID]
FROM BoothComm.UniversalMessageQueue
WHERE
MessagePlatform = 'windows'
AND
MessageCategory = 'accounting'
相同的表,相同的索引,執行計划是絕對相同的。 除MessagePlatform值外,其他所有內容都相同。 並且引起延遲的值出現在比其他記錄更少的記錄上。
您的查詢很慢,因為該表未規范化。 您不應在每個記錄上都將類別和平台存儲為字符串。 相反,它們應該位於具有整數主鍵的查找表中。 然后,這些鍵將存儲在主表中,並且每個鍵上都具有適當的非聚集索引。 然后,您應該在主表上的列上添加一個聚集索引,該索引應該以升序排序(最好是唯一的整數)。
對於您遇到的實際問題,如果沒有定義聚簇索引,則數據存儲在堆中(即未排序的數據堆)。 您擁有的索引會有所幫助,但由於您使用字符串作為鍵這一事實而使性能受到了限制,並且從字符串的外觀看,這些字符串並不是高度特定的(很多重復)。 SQL Server可能只是簡單地決定進行全面掃描以回答您的問題,因為它估計這比任何其他方法都快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.