标签: query-performance

查询在 SQL Server 2014 中慢 100 倍,行计数假脱机行估计罪魁祸首?

我有一个查询,它在SQL Server 2012中运行800 毫秒,在 SQL Server 2014中运行大约170 秒。我认为我已经将范围缩小到Row Count Spool运营商的基数估计不佳。我已经阅读了一些关于假脱机操作符的内容(例如,这里这里),但我仍然无法理解一些事情:

  • 为什么这个查询需要一个Row Count Spool运算符?我认为正确性没有必要,那么它试图提供什么特定的优化?
  • 为什么 SQL Server 估计到Row Count Spool操作符的连接会删除所有行?
  • 这是 SQL Server 2014 中的错误吗?如果是这样,我将在 Connect 中归档。但我想先有更深入的了解。

注意:我可以将查询重写为 aLEFT JOIN或向表添加索引,以便在 SQL Server 2012 和 SQL Server 2014 中实现可接受的性能。所以这个问题更多地是关于深入理解这个特定的查询和计划,而不是关于如何用不同的方式表达查询。


慢查询

请参阅此 Pastebin以获取完整的测试脚本。这是我正在查看的特定测试查询:

-- Prune any existing customers from the set of potential new customers
-- This query is much slower than …
Run Code Online (Sandbox Code Playgroud)

performance sql-server sql-server-2014 cardinality-estimates query-performance

13
推荐指数
3
解决办法
4673
查看次数

SELECT TOP 1 损害查询性能;有没有一种 dba 可访问的方法来克服这个问题?

在生产应用程序(C# 与 SQL Server 2014 Standard 对话)中,有一个如下所示的查询。大多数情况下,它以毫秒为单位运行。但偶尔(对于 的某些值@Id),它会发疯并需要一分钟左右的时间。这比应用超时时间长,因此用户的应用失败。

在“疯了”的情况下,返回的结果集是正确的,因为它在许多但不是所有其他情况下都是空的。

幸运的是,这在生产和开发环境中都是可重现的。

开发人员说从查询中删除“TOP 1”,然后确保应用程序使用结果集的额外行,清除性能问题。

查询规划器在TOP 1存在时建议没有索引。(在开发中)。

正在更改查询并修复应用程序。推出需要一段时间。

我的问题:是否有任何 DBA 可访问的方法来调整或调整生产 SQL Server 实例以在新查询推出应用程序更改之前解决此问题?

SELECT TOP 1
       subscription_id 
  FROM subscription AS sub
  JOIN billing_info AS bi ON bi.billing_info_id = sub.billing_info_id   
  JOIN person_group AS apg ON apg.person_id = bi.person_id
  JOIN pplan ON pplan.plan_id = sub.plan_id
  JOIN product ON product.product_id = [plan].product_id 
  JOIN product_attribute ON product_attribute.product_id = product.product_id 
 WHERE apg.group_id = @Id
   AND apg.start_date < GETDATE()
   AND (apg.end_date IS NULL …
Run Code Online (Sandbox Code Playgroud)

performance sql-server database-tuning query-performance

13
推荐指数
1
解决办法
1650
查看次数

postgres_fdw 性能很慢

以下对外部的查询在 320 万行上执行大约需要 5 秒:

SELECT x."IncidentTypeCode", COUNT(x."IncidentTypeCode") 
FROM "IntterraNearRealTimeUnitReflexes300sForeign" x 
WHERE x."IncidentDateTime" >= '05/01/2016' 
GROUP BY x."IncidentTypeCode" 
ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)

当我在普通表上执行相同的查询时,它会在 0.6 秒内返回。执行计划完全不同:

普通表

SELECT x."IncidentTypeCode", COUNT(x."IncidentTypeCode") 
FROM "IntterraNearRealTimeUnitReflexes300sForeign" x 
WHERE x."IncidentDateTime" >= '05/01/2016' 
GROUP BY x."IncidentTypeCode" 
ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)

外表

Sort  (cost=226861.20..226861.21 rows=4 width=4) (actual time=646.447..646.448 rows=7 loops=1) 
  Sort Key: "IncidentTypeCode" 
  Sort Method: quicksort  Memory: 25kB 
  -> HashAggregate (cost=226861.12..226861.16 rows=4 width=4) (actual  time=646.433..646.434 rows=7 loops=1)
     Group Key: "IncidentTypeCode"
     -> Bitmap Heap Scan on "IntterraNearRealTimeUnitReflexes300s" x  (cost=10597.63..223318.41 rows=708542 width=4) …
Run Code Online (Sandbox Code Playgroud)

postgresql performance postgresql-fdw postgresql-9.5 query-performance

13
推荐指数
1
解决办法
5882
查看次数

用于有效范围聚合查询的数据库?

作为一个简化的例子,假设我有一个这样的表:

seq | value
----+------
102 | 11954
211 | 43292
278 | 19222
499 |  3843
Run Code Online (Sandbox Code Playgroud)

该表可能包含数亿条记录,我需要经常做这样的查询:

SELECT sum(value) WHERE seq > $a and seq < $b
Run Code Online (Sandbox Code Playgroud)

即使seq被索引,典型的数据库实现也会遍历每一行以计算最佳情况下的总和O(n),其中n是范围的大小。

是否有任何数据库可以像O(log(n))每个查询一样有效地执行此操作?

我所遇到的数据结构称为段树所描述这里有时也称为范围树或区间树,尽管所有这些名称通常被描述为数据结构的略微不同的变体。

但是,我还没有遇到任何实现这种数据结构的数据库。对于内存结构来说,从头开始实现它很容易,但如果它必须持久化或太大而无法放入内存,则变得棘手。如果有一种在现有数据库之上实现这一点的有效模式,那也会有所帮助。

旁注:这不是仅附加表,因此在这种情况下,诸如保留累积总和之类的解决方案将不起作用。

performance database-design database-recommendation database-internals query-performance

13
推荐指数
2
解决办法
3250
查看次数

为什么选择此查询的所有结果列比选择我关心的一列更快?

我有一个查询,其中使用select *不仅读取少得多,而且使用的 CPU 时间也比使用select c.Foo.

这是查询:

select top 1000 c.ID
from ATable a
    join BTable b on b.OrderKey = a.OrderKey and b.ClientId = a.ClientId
    join CTable c on c.OrderId = b.OrderId and c.ShipKey = a.ShipKey
where (a.NextAnalysisDate is null or a.NextAnalysisDate < @dateCutOff)
    and b.IsVoided = 0
    and c.ComplianceStatus in (3, 5)
    and c.ShipmentStatus in (1, 5, 6)
order by a.LastAnalyzedDate
Run Code Online (Sandbox Code Playgroud)

这以 2,473,658 次逻辑读取结束,大部分在表 B 中。它使用了 26,562 个 CPU,持续时间为 7,965。

这是生成的查询计划:

从选择单个列的值进行计划 关于 PasteThePlan:https ://www.brentozar.com/pastetheplan/ ? …

performance sql-server execution-plan sql-server-2014 query-performance

13
推荐指数
1
解决办法
2051
查看次数

为什么使用 GROUP BY 子句的聚合查询比不使用 GROUP BY 子句要快得多?

我只是很好奇为什么聚合查询使用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 而第一个查询没有。

Query1 执行计划 Query2 执行计划

如果 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

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

处理 CXPACKET 等待 - 设置并行成本阈值

作为我之前关于对 Sharepoint 站点进行性能故障排除的问题的后续问题,我想知道我是否可以对 CXPACKET 等待做些什么。

我知道下意识的解决方案是通过将 MAXDOP 设置为 1 来关闭所有并行性 - 听起来是个坏主意。但另一个想法是在并行开始之前增加成本阈值。执行计划成本的默认值 5 相当低。

所以我想知道是否已经写了一个查询,可以找到执行计划成本最高的查询(我知道你可以找到那些执行持续时间最长的查询等等 - 但是执行计划成本是否可以在某处检索,也是?),这也会告诉我这样的查询是否已并行执行。

有没有人手头有这样的脚本,或者可以向我指出相关的 DMV、DMF 或其他系统目录视图的方向以找出这一点?

performance sql-server-2008 parallelism query-performance performance-tuning

12
推荐指数
1
解决办法
3028
查看次数

PostgreSQL 顺序扫描而不是索引扫描 为什么?

大家好 我的 PostgreSQL 数据库查询有问题,想知道是否有人可以提供帮助。在某些情况下,我的查询似乎忽略了我创建的用于连接两个表datadata_area. 发生这种情况时,它使用顺序扫描并导致查询速度慢得多。

顺序扫描(~5 分钟)

Unique  (cost=15368261.82..15369053.96 rows=200 width=1942) (actual time=301266.832..301346.936 rows=153812 loops=1)
   CTE data
     ->  Bitmap Heap Scan on data  (cost=6086.77..610089.54 rows=321976 width=297) (actual time=26.286..197.625 rows=335130 loops=1)
           Recheck Cond: (datasetid = 1)
           Filter: ((readingdatetime >= '1920-01-01 00:00:00'::timestamp without time zone) AND (readingdatetime <= '2013-03-11 00:00:00'::timestamp without time zone) AND (depth >= 0::double precision) AND (depth <= 99999::double precision))
           ->  Bitmap Index Scan on data_datasetid_index  (cost=0.00..6006.27 rows=324789 width=0) (actual time=25.462..25.462 rows=335130 loops=1)
                 Index Cond: …
Run Code Online (Sandbox Code Playgroud)

postgresql performance execution-plan query-performance

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

过多的空闲连接会影响 PostgreSQL 9.2 的性能吗?

我的数据库服务器上的一些查询似乎需要很长时间才能响应,而且我认为 CPU 使用率很高。运行时ps aux,我看到大约 250 个“空闲”连接(我认为太多了)。我还没有开始做一个完整的诊断,但我想知道这是否是一个开始寻找的好地方。

我还将 PgBouncer 与事务级池一起使用。我怀疑我可以idle通过调整池大小轻松减少连接数。但是,除非有充分的理由,否则我不想开始做太多更改。

idlePostgreSQL 9.2 中的很多连接会影响性能吗?

非常感谢!

postgresql performance database-design query-performance

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

是否可以避免文件排序?

对于以下 SELECT 查询,是否可以避免“使用临时”和“使用文件排序”?我想不出办法做到这一点。

我尝试为 top_expire 和 program 添加索引,但没有帮助 ORDER BY 查询需要 1 秒以上,而没有它在 localhost 上仅为 0.003 秒

询问

SELECT ad.*, p.link
    FROM (SELECT ad.*
        FROM mod_ad ad 
        JOIN mod_ad_auta auta ON ad.id = auta.ad_id
        WHERE ad.active != 0 AND ad.usr_active != 0 AND ad.expire > 1371151608  AND ad.cat_id = '1' AND ad.price <= '10000' 
          AND auta.rocnik BETWEEN '1950' AND '2013' 
          AND auta.km BETWEEN '0' AND '500000'
        ORDER BY top_expire DESC, program DESC,  ad.id DESC  LIMIT 0,10) as ad
JOIN pages …
Run Code Online (Sandbox Code Playgroud)

mysql performance query-performance

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