[英]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.