【问题标题】:Improve execution time of select distinct query提高选择不同查询的执行时间
【发布时间】:2018-10-05 07:50:18
【问题描述】:

我在获取以下查询的完整结果集时遇到问题。当我选择不同的前 10000 名时,我会在几秒钟内得到结果。当我把它拿出来时,它会持续运行 1 个多小时。我检查并尝试索引诸如 company reg num + country inc 之类的字段,但没有区别。 Toad 建议添加以下索引:

USE [BW_DCF];
    GO
CREATE NONCLUSTERED INDEX [idx_Nonclustered_WeccoParty_OverallStatus]
ON [CORE].[WeccoParty]
([OverallStatus])
INCLUDE (
[GtId], [CrmPartyId], [FirstName], [LastName], [LegalName], [CountryInc], 
[BusinessClass], [RmFullName], [PbeFullName], [OverallClientStatus], 
[OverallRpStatus], [CompanyRegNum] 
)
WITH
(
PAD_INDEX = OFF,
FILLFACTOR = 100,
IGNORE_DUP_KEY = OFF,
STATISTICS_NORECOMPUTE = OFF,
ONLINE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON,
DATA_COMPRESSION = NONE
)
ON [BW_DCF_Group1];
GO



   select distinct wp1.GtId, 
  wp1.CrmPartyId, 
  wp1.LegalName, 
  wp1.BusinessClass, 
  wp1.RmFullName, 
  wp1.PbeFullName, 
  wp1.OverallClientStatus, 
  wp1.OverallRpStatus, 
  wp1.FirstName,
  wp1.LastName,  
  wp1.LegalName,
  wp1.CountryInc,
  wp1.CompanyRegNum,
  wp2.GtId, 
  wp2.CrmPartyId, 
  wp2.LegalName, 
  wp2.BusinessClass, 
  wp2.RmFullName, 
  wp2.PbeFullName, 
  wp2.OverallClientStatus, 
  wp2.OverallRpStatus,  
  wp2.FirstName,
  wp2.LastName,
  wp2.LegalName,
  wp2.CountryInc,
  wp2.CompanyRegNum
     from CORE.WeccoParty wp1
      join CORE.WeccoParty wp2 on   wp1.CompanyRegNum = wp2.CompanyRegNum
                    and wp1.CountryInc = wp2.CountryInc     
                    and wp1.GtId <> wp2.GtId 
                and wp1.OverallStatus = 'Onboarded'
            and wp2.OverallStatus = 'Onboarded'

【问题讨论】:

  • 可以添加执行计划吗?
  • 是的,我现在添加了
  • 如果wp1.GtId &lt;&gt; wp2.GtId 是违规者,我不会感到惊讶。您可以发布 DDL 和您的表上的任何索引吗?对于计划,请使用Paste The Plan,图片没有帮助。
  • 不过,看看那张图片,所有这些都是聚集索引扫描(不是搜索)。我不知道你的表中有多少行,但我怀疑有很多。因此,SQL Server 正在检查 每一 行的值,它没有使用索引来使事情变得更容易。良好的索引可能会有所帮助。

标签: sql sql-server sqlperformance


【解决方案1】:

感谢您添加执行计划。我只能给你一些建议。

  1. 谓词OverallStatus = 'Onboarded' 是选择数据进行比较的选项。它从 CORE.WeccoParty 的总行中选择了多少行?如果它小于
  2. 如果需要从 CORE.WeccoParty 中选择的数据多于 5-10%,最好对此表执行全扫描以消除选择数据,方法是使用两个索引,然后通过哈希运算连接结果.
  3. 看起来 wp1 和 wp2 选择的数据之间的连接是由合并操作执行的。此操作需要首先对 wp1 和 wp2 的输入数据进行排序,尝试通过添加 hash join 提示来消除它:

FROM CORE.WeccoParty wp1 INNER HASH JOIN CORE.WeccoParty wp2 on
wp1.CompanyRegNum = wp2.CompanyRegNum

或嵌套循环连接:

FROM CORE.WeccoParty wp1 INNER LOOP JOIN CORE.WeccoParty wp2 on
wp1.CompanyRegNum = wp2.CompanyRegNum

  1. 您也可以尝试创建支持索引并测试性能

创建索引 IX_WeccoParty_1 ON CORE.WeccoParty(OverallStatus,CompanyRegNum,CountryInc,GtId)

  1. 您是否尝试更新 CORE.WeccoParty 表的统计信息。

通过查看执行计划,我敢打赌,这个合并连接可能是罪魁祸首加上在连接数据之前提取数据。

【讨论】:

    【解决方案2】:

    查询时间过长通常是由于 RAM 空间溢出或给定 RAM 空间不足的数据库。这个查询是完全正常的,实际上并没有任何可能的性能提升。

    作为一种解决方案,我会给数据库更多的内存来使用。

    根据我的经验,我发现 sql-server 在 RAM 空间不足时会出现很大的问题。 PostgreSQL 似乎处理它的速度要快得多。

    【讨论】:

    • 感谢您的反馈 :) 感谢。
    • @Shuumi 你是怎么得出RAM​​是问题的结论的? OP 根本没有提到 RAM 的数量。毫无疑问,我怀疑 PostgreSQL 服务器在使用少量 RAM 的情况下也可能运行不佳。例如,设计不佳的数据库或编写不佳的查询将运行不佳,无论其运行的资源或环境如何(我并不是说 OP 的查询编写不当,或者数据库设计不佳。我不'没有足够的信息来说明)。
    • @Larnu 这只是我的经验。他的查询看起来很简单,即使是复杂的查询,一个多小时的运行时间也很少见。 Postgre的东西实际上是由我测试的。我建立了两个类似的数据库,但给它们的 RAM 太少了。 PostgreSQL 的执行速度更快。我知道这是一个轻率的回答,没有提供足够的信息来总结我所说的话,但我只是根据自己的经验抛出了一个事实。它起作用的事实只是一个有根据的猜测的快乐意外。
    • 通过优化查询,您将减少内存和运行时成本 - 所以这应该首先完成。
    • @PowerStat 确实如此。 OP 的查询计划显示一切都是 Scan,而不是 Seek,因此没有多少 RAM 可以解决问题。
    猜你喜欢
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 2022-01-06
    相关资源
    最近更新 更多