提高不同的查询性能

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;

并使用上述索引。

【讨论】:

以上是关于提高不同的查询性能的主要内容,如果未能解决你的问题,请参考以下文章

结合关系查询提高 Postgres jsonb 查询的性能

为啥手动实现哈希标签可以提高查询的性能?

如何提高查询性能?

使用子查询时如何提高查询性能

提高这个慢查询的性能

SQL 查询执行时间过长。需要提高查询的性能