如何减少自联接查询的逻辑读取?

时间:2019-09-09 13:04:25

标签: sql sql-server performance indexing self-join

我有以下查询:

SELECT DISTINCT
LEFT(REPLACE(PEREWNOMETET.WNT_CODEARTICLE, 'P', ''), 5) AS CI, 
Reference

FROM WNOMETET AS PEREWNOMETET
JOIN WNOMELIG AS PEREWNOMELIG ON PEREWNOMELIG.WNL_NATURETRAVAIL = PEREWNOMETET.WNT_NATURETRAVAIL AND PEREWNOMELIG.WNL_ARTICLE = PEREWNOMETET.WNT_ARTICLE AND PEREWNOMELIG.WNL_MAJEUR = PEREWNOMETET.WNT_MAJEUR
JOIN WNOMELIG AS FILSWNOMELIG ON FILSWNOMELIG.WNL_ARTICLE=PEREWNOMELIG.WNL_COMPOSANT
JOIN ARTICLE AS COMPOSANT ON COMPOSANT.GA_ARTICLE=FILSWNOMELIG.WNL_COMPOSANT
JOIN APP_PIECES_RECHANGE ON Reference=FILSWNOMELIG.WNL_CODECOMPOSANT
WHERE COMPOSANT.GA_LIBREART1 = 'COM'
AND PEREWNOMETET.WNT_CODITI = 'STA'

以及以下统计信息:

(74944 ligne(s) affectée(s))
Table 'Worktable'. Nombre d'analyses 0, lectures logiques 0, lectures physiques 0, lectures anticipées 0, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.
Table 'APP_PIECES_RECHANGE'. Nombre d'analyses 1, lectures logiques 26, lectures physiques 0, lectures anticipées 0, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.
Table 'WNOMELIG'. Nombre d'analyses 10, lectures logiques 243780, lectures physiques 0, lectures anticipées 0, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.
Table 'ARTICLE'. Nombre d'analyses 5, lectures logiques 1062, lectures physiques 0, lectures anticipées 0, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.
Table 'WNOMETET'. Nombre d'analyses 5, lectures logiques 419, lectures physiques 0, lectures anticipées 0, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.
Table 'Worktable'. Nombre d'analyses 0, lectures logiques 0, lectures physiques 0, lectures anticipées 0, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.

我的问题是关于表“ WNOMELIG”的逻辑读取(=演讲逻辑)。 该表是1.67GB,查询正在读取1.86GB,这太多了。我想减少该表的逻辑读取量,但我真的不知道该怎么做。

此表上有两个索引:

- Clustered Index : WNL_NATURETRAVAIL (ASC), WNL_ARTICLE (ASC), WNL_MAJEUR(ASC), WNL_GUID (ASC)
- Non Clustered Index : WNL_NATURETRAVAIL (ASC), WNL_COMPOSANT (ASC)
- Non Clustered Index : WNL_ARTICLE (ASC)

执行计划: https://www.brentozar.com/pastetheplan/?id=HJ2OpT78S

有人可以给我一些有关此问题的见解吗? 谢谢!

1 个答案:

答案 0 :(得分:0)

您的SELECT子句不需要两个连接,而仅仅是查找。因此,您可以将它们放在我认为它们属于的WHERE子句中:

select distinct
  left(replace(wnt.wnt_codearticle, 'P', ''), 5) as ci, 
  fwnl.wnl_codea as reference
from wnometet as wnt
join wnomelig as pwnl on pwnl.wnl_naturetravail = wnt.wnt_naturetravail
                     and pwnl.wnl_article = wnt.wnt_article
                     and pwnl.wnl_majeur = wnt.wnt_majeur
join wnomelig as fwnl on fwnl.wnl_article = pwnl.wnl_a
where wnt.wnt_coditi = 'STA'
and fwnl.wnl_a in (select ga_article from article where ga_libreart1 = 'COM')
and fwnl.wnl_codea in (select reference from app_pieces_rechange);

现在检查...

  • 是否真的需要查找匹配的app_pieces_rechange行。否则,您可以删除该子句。
  • 是否仍然需要DISTINCTDISTINCT非常昂贵,因此,只要有可能,请尽量避免在整个查询中创建重复项。

以下是您可能要提供的索引:

create idx01 on article (ga_libreart1, ga_article);
create idx02 on wnomelig (wnl_a, wnl_article, wnl_codea);
create idx03 on wnomelig (wnl_a, wnl_naturetravail, wnl_article, wnl_majeur);
create idx04 on wnomelig (wnl_article, wnl_a, wnl_codea);
create idx05 on wnomelig (wnl_naturetravail, wnl_article, wnl_majeur, wnl_a);
create idx06 on wnometet (wnt_coditi, wnt_naturetravail, wnt_article, wnt_majeur, wnt_codearticle);
create idx07 on wnometet (wnt_naturetravail, wnt_article, wnt_majeur, wnt_coditi, wnt_codearticle);

这些索引比需要的更多,但是该索引为DBMS提供了多种遍历表的方式。查看执行计划,看看使用了哪些,然后删除其他。

相关问题