【问题标题】: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 及更高版本中可用。近似版本不做排序,不使用临时空间和更少的内存。

标签: sql oracle performance query-optimization


【解决方案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;

并使用上述索引。

【讨论】:

    猜你喜欢
    • 2013-08-03
    • 2021-08-03
    • 2013-02-17
    • 2021-12-15
    • 2014-04-09
    • 2013-01-16
    • 2013-09-26
    • 2011-12-03
    相关资源
    最近更新 更多