我只是很好奇为什么聚合查询使用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 …Run Code Online (Sandbox Code Playgroud) performance sql-server-2005 aggregate parallelism query-performance
我正在运行 MySQL 服务器,以在 Debian 作为来宾操作系统的 VM (VMWare) 上进行测试。来宾有四个模拟 CPU 内核,因此我将 thread_concurrency 设置为四个。
我在大型表上执行昂贵的连接,这可能需要几分钟,但我在来宾操作系统上看到,一次只使用一个核心。无论用于所涉及的表的存储引擎如何(使用 MyISAM 和 InnoDB 测试),都会发生这种情况。此外,在执行这些大型查询时,整个数据库似乎都被阻塞了,我无法并行执行任何其他查询。奇怪的是 htop 显示,用于查询的核心在查询运行时发生了变化!
为什么会发生这种情况?
这是来自SHOW FULL PROCESSLIST;(没有其他查询)的相关条目:
| 153 | root | localhost | pulse_stocks | Query | 50 | Copying to tmp table |
SELECT DISTINCT * FROM
`pulse_stocks`.`stocks` sto,
`pulse_new`.`security` sec
WHERE
(sto.excntry = sec.excntry AND sto.stock_id = sec.ibtic) OR
( sto.isin = sec.isin AND sto.isin <> "" AND sec.isin <> "" )
ORDER BY
sto.id
LIMIT 0, 30
Run Code Online (Sandbox Code Playgroud)
没有其他待处理的查询。另一个有趣的观察是,如果我省略这 …
如果实例MAXDOP设置为 1 并且查询提示用于允许特定查询并行执行,SQL 是否仍使用并行成本阈值值来决定是否实际并行执行?
我一直无法挖掘出这些特定信息,尽管此链接表明如果MAXDOP为 1 ,则 CTFP 将被忽略。这在没有查询提示的情况下是有意义的,因为没有请求,无论成本如何,当MAXDOP为 1时都会并行。
谁能让我知道这两个请求的预期行为是什么?
示例 1:
Instance Maxdop: 1
CTFP: 50
Query hint: Maxdop=2
Query cost: 30
Run Code Online (Sandbox Code Playgroud)
示例 2:
Instance Maxdop: 1
CTFP: 50
Query hint: Maxdop=2
Query cost: 70
Run Code Online (Sandbox Code Playgroud) DROP TABLE IF EXISTS #EmptyTable, #BigTable
CREATE TABLE #EmptyTable(A int);
CREATE TABLE #BigTable(A int);
INSERT INTO #BigTable
SELECT TOP 10000000 CRYPT_GEN_RANDOM(3)
FROM sys.all_objects o1,
sys.all_objects o2,
sys.all_objects o3;
Run Code Online (Sandbox Code Playgroud)
WITH agg
AS (SELECT DISTINCT a
FROM #BigTable)
SELECT *
FROM #EmptyTable E
INNER HASH JOIN agg B
ON B.A = E.A;
Run Code Online (Sandbox Code Playgroud)
这是我今天之前没有注意到的现象的简化再现。我对内部散列连接的期望是,如果构建输入为空,则不应执行探测端,因为连接不会返回任何行。上面的示例与此相反,并从表中读取了 1000 万行。这使查询的执行时间增加了 2.196 秒 (99.9%)。
OPTION (MAXDOP 1)执行计划从#BigTable. 该ActualExecutions是0对哈希连接内所有的运营商。SELECT * FROM #EmptyTable E INNER …标量 UDF 强制执行整体串行计划,这是有据可查的。
给定大量行进入管道中必须计算 UDF 的点,为什么引擎不能将它们分配给处理器?如果 UDF 中没有状态,那么顺序应该无关紧要。
有人声称 UDF 是一个必须使用光标的黑匣子。我可以看到,对于在迭代之间维护某些状态但似乎应该可以并行化的情况,用户游标无法在 SP 中并行化。
解释为什么引擎强制整个计划是串行的,而不仅仅是 UDF 计算阶段的额外要点。
对并行 UDF 的支持是一个合理的要求吗?
我的一个查询在发布后以串行执行模式运行,我注意到在从应用程序生成的 LINQ to SQL 查询中引用的视图中使用了两个新函数。所以我将这些 SCALAR 函数转换为 TVF 函数,但查询仍然以串行模式运行。
早些时候我在其他一些查询中做了 Scalar 到 TVF 的转换,它解决了强制串行执行的问题。
这是标量函数:
CREATE FUNCTION [dbo].[FindEventReviewDueDate]
(
@EventNumber VARCHAR(20),
@EventID VARCHAR(25),
@EventIDDate BIT
)
RETURNS DateTime
AS
BEGIN
DECLARE @CurrentEventStatus VARCHAR(20)
DECLARE @EventDateTime DateTime
DECLARE @ReviewDueDate DateTime
SELECT @CurrentEventStatus = (SELECT cis.EventStatus
FROM CurrentEventStatus cis
INNER JOIN Event1 r WITH (NOLOCK) ON (cis.Event1Id = r.Id)
WHERE (r.EventNumber = @EventNumber) AND r.EventID = @EventID)
SELECT @EventDateTime = (SELECT EventDateTime FROM Event1 r
WHERE (r.EventNumber = @EventNumber) AND r.EventID = …Run Code Online (Sandbox Code Playgroud) performance sql-server parallelism functions query-performance performance-tuning
一般设置并行性的最佳实践是什么?我知道 SQL Server 默认0使用所有可用的处理器,但是在什么情况下您要更改此默认行为?
我记得在某处读到过(我必须寻找这篇文章),对于 OLTP 工作负载,您应该关闭并行性(将 maxdop 设置为1)。我不认为我完全理解你为什么要这样做。
您什么时候将 maxdop 保持到 SQL Server (0)?您何时会关闭并行性 (1)?您何时会明确说明特定数量的处理器的 maxdop?
什么导致并行?
我有一个非常大的查询(约 630 行),它涉及大量嵌套SELECT语句并从多个视图中提取。我们的 SQL Server 将并行度设置为 2,阈值为 95(这样设置是因为我们的 DBA 正在根据其他一些应用程序对其进行优化)。此查询最近开始需要 5-10 分钟才能完成,而通常不到一分钟。在调查原因时,我们注意到它似乎永远不会触发并行,总是串行运行,并怀疑这可能与它的性能有关。奇怪的是,在实验过程中,我们甚至将阈值降回了默认值 5 秒,它仍然无法并行运行。什么可以阻止它?
我们一直在当时没有其他人使用的非生产环境中进行测试,因此这是唯一运行的查询。我们的DBA也尝试过清除缓存和计划,甚至回收系统,但都没有效果。
更新 1:根据评论,我已经确认统计数据每晚更新,但问题仍然存在。我们实际上将代码回滚到没有如此严重性能问题的早期版本,但将继续测试此代码,因为它应该提高旧代码的性能,并且在初始测试中确实做到了。将在此处相应地更新。
我希望尝试使用不同的参数但同时多次运行相同的存储过程。
我正在使用 SQL 2014
这样做的原因是该过程需要大约 7 个小时才能完成。它实际上多次执行相同的过程。因此,例如它可能会为每个分支构建一个新的数据库和表。
我想要做的是分解存储过程,以便我可以在每个分支中运行,然后并行运行每个查询。我已经通过在单独的查询窗口中运行它进行了测试,它的运行速度提高了近 80%。
谁能给我一份关于并行运行查询的傻瓜指南?
我听说过关于并行选择查询的内存授予的相互矛盾的事情:
是哪个?
parallelism ×10
sql-server ×8
functions ×2
performance ×2
aggregate ×1
concurrency ×1
innodb ×1
maxdop ×1
memory-grant ×1
myisam ×1
mysql ×1
optimization ×1