标签: execution-plan

相同的模式、相同的数据、相同的执行计划?

我在 SQL Server 2014 SP2 中有一个 T-SQL 存储过程,它在服务器上花费的时间是我在本地环境中花费的时间的 3 倍。

我将本地数据库恢复到服务器上的数据库,因此架构和数据是相同的。

我是一名程序员,并不是真正的 DBA,所以请耐心等待。

在您查看 XML 之前,执行计划似乎是相同的。在我的本地环境中,Stream Aggregate 用于其中一个查询以进行不同的选择,而在服务器上,它看起来像是 Sort 与散列一起使用。

服务器的处理器比我的(野兽)本地机器少的事实似乎导致了这个问题。每个查询在服务器上都需要更长的时间。这可能是在服务器上选择排序/散列而不是流聚合的原因吗?

有没有办法强制流聚合?

这是存储过程的 SQL:http : //pastebin.com/kkXM3Bsf

这是我本地环境的执行计划:http : //pastebin.com/0u7SHxnM

这是服务器的执行计划:http : //pastebin.com/9sE9DfM0

sql-server execution-plan sql-server-2014

3
推荐指数
1
解决办法
98
查看次数

如何诊断 try_parse 非常慢?

我有一个非常大的查询,它的运行速度比我想象的要慢,但是对查询执行计划的深入研究并没有帮助揭示这种缓慢。最终我缩小了范围:try_parse是罪魁祸首!

正常查询:

SELECT CloseDate
FROM MyTable

(4959 row(s) affected)

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 17 ms.
Run Code Online (Sandbox Code Playgroud)

使用 try_parse:

SELECT try_parse(CloseDate as datetime using 'en-us')
FROM MyTable

(4959 row(s) affected)

SQL Server Execution Times:
   CPU time = 719 ms,  elapsed time = 718 ms.
Run Code Online (Sandbox Code Playgroud)

后一种情况下的执行计划看起来很无辜:

在此处输入图片说明

有没有什么方法可以让我以后更容易地发现罪魁祸首?缓慢的实际来源完全隐藏在视线之外。

performance sql-server execution-plan sql-server-2012

3
推荐指数
1
解决办法
394
查看次数

在子选择中,使用 GetDate 而不是 @variable 会导致更糟糕的执行计划

执行计划

这是现实生活问题的简化版本。GetDate在子选择中使用时,计划更糟且不同。2个查询:

select * , (select count(1) 
            from hamsfa.customer as sub 
            where sub.tstamp_nosync > @old 
              and sub.cus_id > main.cus_id) as x 
from hamsfa.customer as main ;


select * , (select count(1) 
            from hamsfa.customer as sub 
            where sub.tstamp_nosync > dateadd(year, -100, getdate())
              and sub.cus_id > main.cus_id) as x 
from hamsfa.customer as main ;
Run Code Online (Sandbox Code Playgroud)

我不完全理解的是为什么。

变量应该按我的理解变差。

还有另一个查询,这导致了几乎 700% 的差异(1s 与 7s)。

所以问题是:为什么一个变量会产生更好的计划,即使根据我的经验它应该更糟?

编辑:统计数据是最新且正确的

sql-server execution-plan

3
推荐指数
1
解决办法
386
查看次数

有没有更快的方法来计算 JSONB 标签?

我试图在 Postgres 9.5 中从这个查询中挤出更多的性能。我正在运行超过 400,000 行。

在玩弄它时,我注意到这些CASE语句增加了相当多的查询成本 - 如果我用简单地对一些现有列求和来替换它们,它会将执行时间减半。有没有更有效的方法来计算这些总和?

SELECT sum("tag1"), sum("tag2"), sum("total_tags")
FROM (
    SELECT people.data->'recruiter_id' AS recruiter_id,
          (CASE WHEN people.data->'tags' ? 'tag1' THEN 1 END) AS "tag1",
          (CASE WHEN people.data->'tags' ? 'tag2' THEN 1 END) AS "tag2", 
          ((CASE WHEN people.data->'tags' ? 'tag1' THEN 1 ELSE 0 END) +
           (CASE WHEN people.data->'tags' ? 'tag2' THEN 1 ELSE 0 END)) AS total_tags
    FROM people WHERE people.data->'tags' ?| ARRAY['tag1','tag2'] ) AS target
GROUP BY recruiter_id
Run Code Online (Sandbox Code Playgroud)

的输出EXPLAIN ANALYSE: …

postgresql performance statistics execution-plan json postgresql-performance

3
推荐指数
1
解决办法
1975
查看次数

条件子查询

我有以下查询:

SELECT id,
   email,
   first_name as "firstName",
   last_name as "lastName",
   is_active as "isActive",
   password,
   access,
   CASE
     WHEN access < 3 THEN (
       SELECT
         CASE WHEN count(*) = 1 THEN true ELSE false END
       FROM user_rating_entity ure
       WHERE ure.user_id = u.id
         AND ure.rating_entity_id = :re_id
     )
     ELSE true
   END as "isResponsible"
FROM users u
WHERE u.id = :id
Run Code Online (Sandbox Code Playgroud)

如果access > 3,字段“isResponsible”应直接设置为true,并且不应执行子查询。我在这两种情况下都使用了解释分析,其中 access>=<to 3但我得到了相同的输出。

为什么呢?

postgresql optimization execution-plan subquery explain

3
推荐指数
2
解决办法
1万
查看次数

WHERE IN (1,2,3,4) 与 IN 之间的性能差距(select * from STRING_SPLIT('1,2,3,4',','))

我似乎在对 aSELECT IN和 a使用硬编码值之间存在巨大的性能差距STRING_SPLIT。除了最后一个阶段为STRING_SPLIT代码多次执行索引查找之外,查询计划是相同的。结果是大约 90000 与大约 15000(根据dm_exec_query_stats)的 CPU 时间,因此差异是巨大的。我已经在这里发布了两个计划......

  1. 硬编码计划
  2. 字符串拆分计划

有趣的是查询计划显示的成本几乎相同,但是当我检查dm_exec_query_stats成本 ( last_worker_time)时却大不相同。

这是查询计划的 2 个输出...

0x79DEAD79D1F149CD 16199 
select * 
from fn_get_samples(1) s 
where s.sample_id in 
    (2495,2496,2497,2498,2499,2500,2501,2502,2503,2504)

0x4A073840486B252C 86689 
select * 
from fn_get_samples(1) s 
where s.sample_id in 
    (select value as id 
     from 
     STRING_SPLIT('2495,2496,2497,2498,2499,2500,2501,2502,2503,2504',','))
Run Code Online (Sandbox Code Playgroud)

功能代码是...

CREATE FUNCTION [dbo].[fn_get_samples]
(
    @user_id int
)
RETURNS TABLE
AS
RETURN (
    -- get samples
    select s.sample_id,language_id,native_language_id,s.source_sentence,s.markup_sentence,s.latin_sentence,
        s.translation_source_sentence,s.translation_markup_sentence,s.translation_latin_sentence,
        isnull(sample_vkl.knowledge_level_id,1) as vocab_knowledge_level_id,
        isnull(sample_gkl.grammar_knowledge_level_id,0) as grammar_knowledge_level_id, …
Run Code Online (Sandbox Code Playgroud)

performance sql-server execution-plan string-splitting query-performance

3
推荐指数
1
解决办法
719
查看次数

优化存储过程中的未知数

我在网上看到的所有示例都暗示OPTIMIZE FOR UNKNOWN应用于特定查询。

可以OPTIMIZE FOR UNKNOWN应用于整个存储过程(而不仅仅是特定查询)?如果是,语法是什么?

sql-server stored-procedures execution-plan

3
推荐指数
2
解决办法
6493
查看次数

10195 计划同一个查询!

所以,我运行了 BrentOzar 脚本,它为同一查询确定了 10195 个计划!!!查询如下:

SELECT * 
FROM [table1]
INNER JOIN [table2]
  ON [table1].[versionId] = [table2].[VersionId]
INNER JOIN [table3]
  ON [table2].[ContentId] = [table3].[nodeId]
INNER JOIN [table4]
  ON [table3].[nodeId] = [table4].[id]
WHERE ([table4].[nodeObjectType] = 'abcde123-fgh3-4ijk-8lmn-424f222332ff')
  AND ([table1].[published] = 0 
  AND [table1].[releaseDate] <= '2017-07-22 17:43:47')
  AND ([table1].[newest]=1)
ORDER BY [table2].[VersionDate] DESC, [table4].[sortOrder]
Run Code Online (Sandbox Code Playgroud)

所有 10195 个之间的唯一区别是日期字段(发布日期)。每个计划具有不同日期的值。

关于索引,以下适用:

  • 表 1:nodeid 和 versionid 上的 NC,versionId 上的 C
  • 表 2:版本 ID 上的 NC,ID 上的 C
  • 表 3:节点 ID 上的 NC,pk 上的 C
  • 表 4:nodeObjectType …

performance sql-server execution-plan query-performance

3
推荐指数
1
解决办法
890
查看次数

查找员工工资第二高

想象一下有一个包含这些字段的表:

Employee: E-Number
          E-Name
          Department
          Salary
Run Code Online (Sandbox Code Playgroud)

我们需要编写一个查询来找到这个表中第二高的薪水。

我发现这个查询:

select distinct salary
from Employee e1
where 2 = ( select count(distinct salary)
            from Employee e2
            where e1.salary < e2.salary)
Run Code Online (Sandbox Code Playgroud)

我对这部分有点困惑,where 2 =因为我以前从未见过这样的事情。

任何人都可以在这里解释更多关于查询和部分的信息where 2 =吗?子查询的结果是什么,表行(e1,e2)以什么方式相互比较?

实际上这是执行计划,谁能解释更多步骤?

在此处输入图片说明

sql-server execution-plan sql-server-2012

3
推荐指数
2
解决办法
1064
查看次数

在计划缓存中找不到编译的参数值

我发现,通过查询存储,一个查询平均执行 297582 次逻辑读取。

我想看看我是否能够稍微调整该查询,然后尝试再次执行该查询以查看是否有任何改进。

问题是我在缓存计划中找不到编译参数值。

我错过了什么吗?也许是一些阻止参数值缓存的原因/设置?

即使我以 XML 格式打开执行计划,我也找不到参数。

附加信息:查询由第三方应用程序执行,该应用程序准备语句,然后使用sp_prepare和执行它们sp_execute

完整的 XML 计划

查询存储:在属性选项卡中找不到任何参数

计划缓存 DMV:计划缓存 dmv

sql-server execution-plan parameter plan-cache sql-server-2016

3
推荐指数
1
解决办法
287
查看次数