Rac*_*hel 12 performance sql-server-2005 aggregate parallelism query-performance
我只是很好奇为什么聚合查询使用GROUP BY
子句比没有子句运行得更快。
例如,这个查询需要将近 10 秒才能运行
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
Run Code Online (Sandbox Code Playgroud)
虽然这个只需不到一秒钟
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
Run Code Online (Sandbox Code Playgroud)
CreatedDate
在这种情况下只有一个,因此分组查询返回与未分组查询相同的结果。
我注意到两个查询的执行计划是不同的 - 第二个查询使用 Parallelism 而第一个查询没有。
如果 SQL Server 没有 GROUP BY 子句,它以不同的方式评估聚合查询是否正常?在不使用GROUP BY
子句的情况下,我可以做些什么来提高第一个查询的性能?
编辑
我刚刚了解到我可以使用OPTION(querytraceon 8649)
将并行性的开销开销设置为 0,这使得查询使用一些并行性并将运行时间减少到 2 秒,尽管我不知道使用此查询提示是否有任何缺点。
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
OPTION(querytraceon 8649)
Run Code Online (Sandbox Code Playgroud)
我仍然更喜欢较短的运行时间,因为查询旨在根据用户选择填充一个值,因此理想情况下应该像分组查询一样是即时的。现在我只是结束我的查询,但我知道这并不是一个理想的解决方案。
SELECT Min(CreatedDate)
FROM
(
SELECT Min(CreatedDate) as CreatedDate
FROM MyTable WITH (NOLOCK)
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
) as T
Run Code Online (Sandbox Code Playgroud)
编辑 #2
无论CreatedDate
和SomeIndexedValue
对他们有独立的非唯一,非聚集索引。SomeIndexedValue
实际上是一个 varchar(7) 字段,即使它存储一个指向另一个表的 PK (int) 的数值。数据库中没有定义两个表之间的关系。我根本不应该更改数据库,并且只能编写查询数据的查询。
MyTable
包含超过 300 万条记录,每条记录都被分配到一个它所属的组 ( SomeIndexedValue
)。组可以是 1 到 200,000 条记录
看起来它可能CreatedDate
按照从低到高的顺序跟踪索引并进行查找以评估SomeIndexedValue = 1
谓词。
当它找到第一个匹配的行时,它就完成了,但是在找到这样的行之前,它可能会进行比预期更多的查找(它假设与谓词匹配的行是根据日期随机分布的。)
此查询的理想索引是 one on SomeIndexedValue, CreatedDate
。假设您不能添加或至少将您现有的SomeIndexedValue
封面索引CreatedDate
作为包含列,那么您可以尝试按如下方式重写查询
SELECT MIN(DATEADD(DAY, 0, CreatedDate)) AS CreatedDate
FROM MyTable
WHERE SomeIndexedValue = 1
Run Code Online (Sandbox Code Playgroud)
以防止它使用该特定计划。
归档时间: |
|
查看次数: |
28499 次 |
最近记录: |