Postgres查询离开联接需要太多时间

问题描述

我对此查询有疑问。它进入循环,我的意思是15分钟后查询仍未完成 但是如果删除左连接之一 我在哪里错了?

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

谢谢 E

解决方法

在这种情况下,关联子查询可能是最简单的方法:

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;

这应该比您的版本快很多,这有两个原因。首先,它避免了外部聚集。其次,它避免了表之间的笛卡尔积。

通过在sito上的每个辅助表上创建索引,可以使此过程更快。

,

假设id_usid_invmatid_strutturaid_tafonomia均为PRIMARY KEY CLUSTERED

您应该在连接列上添加索引:

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) ;

比您可以通过以下方式降低复杂性:

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;

应该更快

,

不幸的是,COUNT(DISTINCT ...)在使用索引时难以改进。但是,我们至少可以尝试添加覆盖查询中所有联接的索引:

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);

请注意,上述索引仅有助于连接,不会影响sito的聚合步骤以及每组的不同计数。正如@jarlh在评论中指出的那样,SELECT DISTINCT是多余的,因为您正在使用GROUP BY,所以只需做一个普通的SELECT

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...