提高不同的查询性能
Posted
技术标签:
【中文标题】提高不同的查询性能【英文标题】:Improve distinct query performance 【发布时间】:2019-12-15 11:51:40 【问题描述】:知道如何改进这个查询执行吗? (也许有一些预聚合)?
SELECT p.segment, country, count(distinct userid)
from pixel_data_opt p
WHERE country in ('US')
and segment is not null
GROUP BY p.segment, country;
我尝试了以下方法,但没有帮助 -
select segment, country,sum(cnt)
from
(SELECT p.segment, country, userid,count(*) as cnt
from pixel_data_opt p
WHERE country in ('US')
and segment is not null
GROUP BY p.segment, country,userid
)
group by 1,2;
【问题讨论】:
不要在所有数据库系统的标签上发送垃圾邮件,选择您正在使用的一个并告诉我们它是哪个。这是针对 mysql、Oracle 还是 SQL Server 的? 请标记适当的 RDBMS MySQL SQL Server Oracle。 关于分段、国家和用户 ID 的索引可能会有所帮助,但如果不知道您正在使用的特定 DBMS,我们将无能为力。 Oracle 查询优化是关于平衡许多不同的因素,例如数据量。例如,您在评论中说“行数是千亿”。这是您需要在问题中提供的信息。请阅读this answer on asking Oracle tuning questions 并编辑您的问题以包含所需信息。 一个未提及的选项是使用 approx_count_distinct 而不是 count(distinct ...)。如果您真的不需要 100% 正确的答案,这是可能的,但足够接近的答案就可以了。此功能在 12.1 及更高版本中可用。近似版本不做排序,不使用临时空间和更少的内存。 【参考方案1】:您的第一个查询没有任何问题 - 不过,它可能是 where country = 'US'
- 但优化器(就 Oracle 而言)足够聪明,可以解决这个问题。
country
列是否已编入索引?如果没有,请这样做。
另外,收集有关表的统计信息。
如果您发布更多信息可能会有所帮助,例如涉及的行数,解释计划,因为它显示了数字,这意味着什么。
【讨论】:
主要问题是不同的操作。行数上千亿。 数千亿?那么这个查询需要多长时间才能返回结果呢?【参考方案2】:对于这个查询:
SELECT p.segment, country, count(distinct userid)
FROM pixel_data_opt p
WHERE country in ('US') AND
segment is not null
GROUP BY p.segment, country;
你想在表上建立一个索引。有几种方法。一种合理的选择是:pixel_data_opt(country, segment, userid)
。
我建议将查询重写为:
SELECT p.segment, 'US' as country, count(distinct userid)
FROM pixel_data_opt p
WHERE country in ('US') AND
segment is not null
GROUP BY p.segment;
并使用上述索引。
【讨论】:
以上是关于提高不同的查询性能的主要内容,如果未能解决你的问题,请参考以下文章