【问题标题】:Make a query with DISTINCT clause run faster使带有 DISTINCT 子句的查询运行得更快
【发布时间】:2016-03-04 02:36:40
【问题描述】:

我有以下疑问:

select distinct type, account 
  from balances_tbl 
 where month = 'DEC-12'

balances_tbl 表每月有超过 300 万条记录。不同的类型和帐户行可能大约有 20,000 条记录。 month 列已编入索引。 typeaccount 列也被索引。该查询需要很长时间(大约 30 分钟)才能执行。

有没有办法让DISTINCT 子句的查询更快?

【问题讨论】:

  • 请发布上面选择查询的 EXPLAIN PLAN 的结果,因为它将帮助 SO 上的 Oracle 专家帮助您。
  • 真的需要筛选 20k 条记录吗?
  • 您的表保存了多少个月的数据?
  • 添加计划!!!!!!!!! 是在做全表扫描吗?诸如服务器年龄、性能或流量之类的其他任何东西?没有太多信息可以继续。
  • 以下有帮助吗?

标签: sql oracle distinct


【解决方案1】:

您需要添加一个包含所有三列的索引。我建议对(月份、类型、帐户)进行索引。这样,Oracle 只需扫描索引即可完成工作。

否则,您必须进行全表扫描,然后才能找到唯一的值。

我可能还建议按月对表进行分区。但是,这需要重新组织表格,而且工作量更大。

【讨论】:

    【解决方案2】:

    首先,请与您的 DBA 确认您有该表/索引的最新统计信息。

    那么,对于那个查询来说,30 分钟太长了,没有看到EXPLAIN PLAN,我猜Oracle 正在执行全面扫描,所以它正在访问表中的每一行。鉴于每月大约有 300 万行,这可能是很多行。正如您所说,month 已编入索引,您可以尝试使用以下命令强制对month 进行索引访问:

    select /*+ index(b <index_on_month)>*/ distinct type, account 
    from balances_tbl b
    where month = 'DEC-12'
    

    其中&lt;index_on_month&gt;month 列上的索引名称。由于它是一个与日期相关的字段,因此该索引很可能具有良好的clustering factor

    无论如何,如果没有看到执行计划,很难确定为什么要花这么长时间。

    【讨论】:

      【解决方案3】:

      您可以创建逐月分区或使用可以使用 oracle 优化提示来更快地检索数据

      这些是对你的查询有用的提示

       1) /*+ ALL_ROWS */
       2) /*+ FIRST_ROWS(n) */ 
       3) /*+ parallel */
      

      【讨论】:

        【解决方案4】:

        尝试添加聚合函数并确保月份列上有索引。除非服务器很差,否则我不应该花这么长时间。

        试试:

        select type, 
               account,
               count(*) as dummy
        from   balances_tbl 
        where  month = 'DEC-12'
        group by type,
               account
        

        【讨论】:

          【解决方案5】:

          这是最简单的解决方案 - 不需要索引、计划和所有这些......:

          SELECT DISTINCT d.deptno, dname FROM scott.dept D, scott.emp E WHERE D.deptno = E.deptno
          /  
          -- Same as Distinct --
          SELECT deptno, dname FROM scott.dept D WHERE EXISTS ( SELECT 'X' FROM scott.emp E WHERE E.deptno = D.deptno)
          /
          

          【讨论】:

            猜你喜欢
            • 2016-02-01
            • 1970-01-01
            • 1970-01-01
            • 2021-01-09
            • 2011-09-25
            • 2011-12-11
            • 1970-01-01
            • 2014-11-29
            • 1970-01-01
            相关资源
            最近更新 更多