J'ai un problème avec cette requête. il va en boucle, je veux dire la requête après 15 minutes pas fini Mais si supprimer l'un des travaux de jointure gauche où mal je?

Select distinct a.sito,
Count(distinct a.id_us) as us,
Count (distinct b.id_invmat) as materiali,
Count (distinct c.id_struttura) as Struttura,
Count(distinct d.id_tafonomia) as tafonomia
From us_table as a
Left join invetario_materiali as b on a.sito=b.sito
Left join struttura_table as c on a.sito=c.sito
Left join tafonomia_table as d on a.sito=d.sito
Group by a.sito
Order by us

Merci E

0
enzo cocca 1 sept. 2020 à 10:20

3 réponses

Meilleure réponse

C'est un cas où les sous-requêtes corrélées pourraient être l'approche la plus simple:

select s.sito,
      (select count(*) from invetario_materiali m where s.sito = m.sito) as materiali,
      (select count(*) from struttura_tablest where s.sito = st.sito) as Struttura,
      (select count(*) from tafonomia_table t where s.sito = t.sito) as tafonomia
from (select sito, count(*) as us
      from us_table
      group by sito
     ) s
order by us;

Cela devrait être beaucoup, beaucoup plus rapide que votre version pour deux raisons. Premièrement, cela évite l'agrégation externe. Deuxièmement, il évite les produits cartésiens parmi les tableaux.

Vous pouvez rendre cela encore plus rapide en créant des index sur chacune des tables secondaires sur sito.

2
Gordon Linoff 1 sept. 2020 à 12:08

Malheureusement, COUNT(DISTINCT ...) est difficile à améliorer en utilisant un index. Cependant, nous pouvons au moins essayer d'ajouter des indices qui couvrent toutes les jointures de votre requête:

CREATE INDEX inv_mat_idx ON invetario_materiali (sito, id_invmat);
CREATE INDEX strut_tbl_idx ON struttura_table (sito, id_struttura);
CREATE INDEX taf_tbl_idx ON tafonomia_table (sito, id_tafonomia);

Notez que les indices ci-dessus aideraient uniquement les jointures et n'affecteraient pas l'étape d'agrégation par sito et les nombres distincts par groupe. Comme @jarlh l'a noté dans les commentaires, SELECT DISTINCT est superflu, puisque vous utilisez GROUP BY, alors faites un simple SELECT.

0
Tim Biegeleisen 1 sept. 2020 à 07:26

En supposant que id_us, id_invmat, id_struttura et id_tafonomia sont tous PRIMARY KEY CLUSTERED

Vous devez ajouter des index sur les colonnes de jointure:

CREATE INDEX IX_SITO ON us_table ( sito ASC) ;
CREATE INDEX IX_SITO ON invetario_materiali ( sito ASC) ;
CREATE INDEX IX_SITO ON struttura_table ( sito ASC) ;
CREATE INDEX IX_SITO ON tafonomia_table ( sito ASC) ;

Ensuite, vous pouvez réduire la complexité de cette manière:

with
_us_table as (
    select sito, count(distinct a.id_us) us
    from us_table a
    group by sito
),
_invetario_materiali as (
    select sito, count(distinct b.id_invmat) materiali
    from invetario_materiali b
    group by sito
),
_struttura_table as (
    select sito, count(distinct c.id_struttura) Struttura
    from struttura_table c
    group by sito
),
_tafonomia_table as (
    select sito, count(distinct d.id_tafonomia) tafonomia
    from tafonomia_table d
    group by sito
)
Select a.sito, a.us, b.materiali, c.Struttura, d.tafonomia
From _us_table as a
Left join _invetario_materiali as b on a.sito=b.sito
Left join _struttura_table as c on a.sito=c.sito
Left join _tafonomia_table as d on a.sito=d.sito
Order by a.us;

Devrait être beaucoup plus rapide

1
a_horse_with_no_name 1 sept. 2020 à 12:25