我有以下子查询:
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的新手。
答案 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。
最简单的索引可能是(州,市)
上的一个索引