SQL - 避免额外的 GROUP BY(并提高查询性能)

Posted

技术标签:

【中文标题】SQL - 避免额外的 GROUP BY(并提高查询性能)【英文标题】:SQL - Avoid an additional GROUP BY (and improving query performance) 【发布时间】:2013-02-20 09:38:49 【问题描述】:

我一直在解决这个问题,很高兴听到新的想法:)

我有一张这样的表,里面有数十亿条记录

TAB_IX (int) (PK)
TAB_ID (int) (PK)
PR_ID (int) (PK)
SP_ID (int) (PK)(IX)
....

以前我是这样检索数据的

SELECT TAB_ID, COUNT (SP_ID) as HITS FROM table t
INNER JOIN table_sp s on t.SP_ID = s.ID
WHERE TAB_IX = @tab_inx 
AND PR_ID IN (SELECT PR_ID FROM @pr_id)
AND s.NAME IN (SELECT DISTINCT NAME FROM @sp_names)  
GROUP BY TAB_ID

table_sp 是一个有 10k 条记录的小表(ID (int) (PK), NAME (varchar) (IX))

@pr_id 和@sp_names 是一列的表变量

查询非常快(大约 2-3 秒);现在我不想区分具有不同 PR_ID 和相同 TAB_IX、TAB_ID、SP_ID 的记录

例如像这样的记录

TAB_IX - TAB_ID - PR_ID - SP_ID
1      - 700    - 1     - 100
1      - 700    - 2     - 100

应该被视为一个。

唯一的方法似乎是做一个额外的 GROUP BY

这样

SELECT TAB_ID, COUNT(SP_ID) as HITS FROM (
SELECT TAB_ID, SP_ID, COUNT (PR_ID) FROM table 
WHERE TAB_IX = @tab_inx 
AND PR_ID in (select PR_ID from @pr_id)
AND s.NAME IN (SELECT DISTINCT NAME FROM @sp_names)
GROUP BY TAB_ID, SP_ID) AS DUMMY
GROUP BY TAB_ID

问题在于性能,因为添加这个额外的 GROUP BY 操作看起来很痛苦。

您对改进查询有什么想法吗?

提前致谢:)

【问题讨论】:

【参考方案1】:

我想在原始查询中指定要计算 DISTINCT SP_ID 就可以了

SELECT TAB_ID, COUNT (DISTINCT SP_ID) as HITS FROM table t
INNER JOIN table_sp s on t.SP_ID = s.ID
WHERE TAB_IX = @tab_inx 
AND PR_ID IN (SELECT PR_ID FROM @pr_id)
AND s.NAME IN (SELECT DISTINCT NAME FROM @sp_names)  
GROUP BY TAB_ID

【讨论】:

谢谢ybo,我没有考虑这个解决方案:) 但是性能仍然很相似;很多记录上的这个 DISTINCT 也很重。怕是提高不了查询速度……

以上是关于SQL - 避免额外的 GROUP BY(并提高查询性能)的主要内容,如果未能解决你的问题,请参考以下文章

sql查询中如何用group by查询出完整的一行记录?

PL/SQL Group By question 添加取决于行号的额外列

在 sql 查询中使用聚合函数时避免 group by 子句

优化 SQL:如何重写此查询以提高性能? (使用子查询,摆脱 GROUP BY?)

SQL Group By和窗口函数

PIG Group by 避免包