使用内部连接提高相关子查询的性能

Improve performance of correlated subquery with inner joins

我有以下子查询:

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;  

这可行,但查询效率非常低,并且考虑到基础 table 的大小,需要很长时间。我在考虑使用内部联接可以提高性能,但我还没有尝试过有效的方法。

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

这不是您要查找的连接,而是聚合函数的条件。类似这样

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; 

您仍然会看到执行所有这些替换时的一些效果 - 如果您甚至可以在 table 上创建一个计算的持久列来正确存储字符串,您的查询会执行得更好。

这会有所帮助的原因:不需要引擎扫描 table 两次,它应该能够在一次扫描中完成所有事情,因为您只使用一个 [=18] =] 无论如何。如果您实际上使用的是第二个 table,您会希望使用具有适当 JOIN.

的相同类型的方法

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

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

要查看 io 统计信息,运行 运行 宁 SET STATISTICS IO ON 之后的查询。统计信息将与消息一起显示。

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

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