【发布时间】:2017-09-19 13:05:32
【问题描述】:
我有一个包含超过 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”多 600K。
但是,这个查询会在 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';
通过从查询中删除 Category,可以非常快速地返回响应...
更新 2
我已按要求创建了几个执行计划。然而,我注意到的是,“粘贴计划”实用程序生成的计划中的百分比与我在 SSMS 中得到的百分比似乎不同,所以我在每个链接下方包括了我在管理中看到的百分比工作室。
对于以下查询(有效)...
SELECT MAX([MessageID]) [MaxID] FROM [BoothComm].[UniversalMessageQueue] WHERE [MessagePlatform]='windows';
https://www.brentozar.com/pastetheplan/?id=Sk9q59CqZ
- 0%:选择
- 0%:流聚合
- 0%:顶部
- 100%:索引扫描
下一个查询(不起作用)我只能提供一个ESTIMATED执行计划。
SELECT
MAX(MessageID) AS [MaxID]
FROM BoothComm.UniversalMessageQueue
WHERE
MessageCategory = 'session'
AND
MessagePlatform = 'windows'
https://www.brentozar.com/pastetheplan/?id=r1zqnq09-
- 0%:选择
- 0%:流聚合
- 0%:顶部
- 0% : 嵌套循环(内连接) -- 为什么会出现这种情况??
- 21%:索引扫描
- 79% : Key Lookup -- 也是新的,似乎比其他任何事情都要占用更多的时间
(感谢大家的帮助!)
更新 3
所以在进行了以下所有对话和更改之后,我仍然有一个问题......
为什么这个查询会在 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 值之外,一切都是相同的。并且导致延迟的值出现在比另一个更少的记录上。
【问题讨论】:
-
是
id你的集群密钥吗? -
执行计划显示什么以及它是否使用您的索引?
-
如果将
ID作为INCLUDE添加到索引中怎么样? -
使用Paste The Plan @ brentozar.com 分享您的执行计划,以下是说明:How to Use Paste the Plan。
-
另外,分享您的表架构。
标签: sql-server tsql query-performance