缩短 select 不同查询的执行时间
Improve execution time of select distinct query
我在为下面的查询获取完整结果集时遇到问题。当我 select 不同的前 10000 个时,我会在几秒钟内得到结果。当我取出它时,它会保持 运行 超过 1 小时。我检查并尝试索引公司注册号 + 国家公司等字段,但没有任何区别。 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'
较长的查询时间通常是由于 RAM space 溢出或数据库的 RAM space 不足。这个查询是完全正常的,实际上没有任何性能提升可能。
作为解决方案,我会给数据库更多的 ram 来使用。
根据我的经验,我发现 sql-服务器在缺少 RAM space 时会出现严重问题。 PostgreSQL 似乎可以更快地处理它。
感谢您添加执行计划。我只能给你一些提示。
- Predicate OverallStatus = 'Onboarded' 是 selects 数据进行比较的那个。 CORE.WeccoParty 中的总行数 select 有多少行?如果它小于 <5-10%,您可以尝试在其上创建索引。也可以先用这个predicate过滤后的数据创建一个临时的table然后join它们
- 如果需要从 CORE.WeccoParty 编辑 select 的数据多于 5-10%,最好对此 table 执行全面扫描以消除 select使用两个索引对数据进行离子化,然后通过哈希操作连接结果。
- 看起来由 wp1 和 wp2 编辑的数据 select 之间的连接是由合并操作执行的。此操作需要首先对 wp1 和 wp2 的输入数据进行排序,尝试通过添加哈希连接提示来消除它:
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
- 您也可以尝试创建一个支持索引并测试性能
CREATE INDEX IX_WeccoParty_1
ON CORE.WeccoParty(OverallStatus,CompanyRegNum,CountryInc,GtId)
- 您是否尝试更新 CORE.WeccoParty table.
上的统计信息
通过查看执行计划,我敢打赌这个合并连接可能是罪魁祸首加上在连接数据之前提取数据。
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'
较长的查询时间通常是由于 RAM space 溢出或数据库的 RAM space 不足。这个查询是完全正常的,实际上没有任何性能提升可能。
作为解决方案,我会给数据库更多的 ram 来使用。
根据我的经验,我发现 sql-服务器在缺少 RAM space 时会出现严重问题。 PostgreSQL 似乎可以更快地处理它。
感谢您添加执行计划。我只能给你一些提示。
- Predicate OverallStatus = 'Onboarded' 是 selects 数据进行比较的那个。 CORE.WeccoParty 中的总行数 select 有多少行?如果它小于 <5-10%,您可以尝试在其上创建索引。也可以先用这个predicate过滤后的数据创建一个临时的table然后join它们
- 如果需要从 CORE.WeccoParty 编辑 select 的数据多于 5-10%,最好对此 table 执行全面扫描以消除 select使用两个索引对数据进行离子化,然后通过哈希操作连接结果。
- 看起来由 wp1 和 wp2 编辑的数据 select 之间的连接是由合并操作执行的。此操作需要首先对 wp1 和 wp2 的输入数据进行排序,尝试通过添加哈希连接提示来消除它:
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
- 您也可以尝试创建一个支持索引并测试性能
CREATE INDEX IX_WeccoParty_1 ON CORE.WeccoParty(OverallStatus,CompanyRegNum,CountryInc,GtId)
- 您是否尝试更新 CORE.WeccoParty table. 上的统计信息
通过查看执行计划,我敢打赌这个合并连接可能是罪魁祸首加上在连接数据之前提取数据。