通过内部联接提高相关子查询的性能

时间:2017-03-24 12:32:48

标签: sql postgresql inner-join correlated-subquery

我有以下子查询:

SELECT
  b.state, 
  b.city,
  count(b.state) as totalCount, 
  sum(cast(replace(b.annual_prod, ',','.') as decimal)) AS annualProd, 
  (
    SELECT count(size_k) 
    FROM opentable_clean a  
    WHERE a.state = b.state
      AND a.city = b.city
      AND cast(replace(a.size_k, ',','.') as decimal) >= 20  
    GROUP BY a.state, a.city
  ) as Above20k  
FROM opentable_clean b
GROUP BY b.state, b.city
ORDER by annualProd DESC;  

这样可行,但查询效率非常低,并且考虑到基础表的大小需要很长时间。我在想使用内连接可以提高性能,但我无法尝试一个有效的方法。

任何建议都会有所帮助,因为我是sql的新手。

2 个答案:

答案 0 :(得分:1)

这不是你正在寻找的连接,而是聚合函数的一个条件..这样的事情

select b.state, 
    b.city,  
    count(b.state) as totalCount, 
    sum(cast(replace(b.annual_prod, ',','.') as decimal)) AS annualProd, 
    SUM(CASE 
           WHEN cast(replace(a.size_k, ',','.') as decimal) >= 20 
           THEN 1 
           ELSE 0 END) as Above20k
    FROM opentable_clean b  
    GROUP BY b.state, b.city  
    ORDER by annualProd DESC; 

你仍然可以看到所有这些替换的一些打击 - 如果你甚至可以在表上创建一个计算的持久列来正确存储字符串,那么你的查询会表现得更好。

这将有助于:它不是要求引擎扫描表两次,而是应该能够在一次扫描中完成这一切,因为你只需要使用一个表。如果您实际上正在使用第二个表,那么您需要使用相同类型的方法和适当的JOIN

答案 1 :(得分:0)

如果要提高查询的性能,首先应查看执行计划和io统计信息。

要查看执行计划,请单击显示执行计划按钮。

要查看io统计信息,请在运行SET STATISTICS IO ON后运行查询。统计信息将随消息一起显示。

如果没有索引,此查询将通过tableScan / clusteredIndexScan读取open_table b,然后它将通过tableScan / clusteredIndexScan为每个组分组并读取open_table a。

最简单的索引可能是(州,市)

上的一个索引