SQL调优,长时间运行查询+ rownum

时间:2017-05-25 09:20:59

标签: sql oracle performance query-performance

我在数据库表中有百万条记录,其中包含帐户号,地址和更多列。我想要使​​用desc顺序排序100行,我使用了rownum,但是查询需要很长时间才能执行,因为它首先扫描整个表,然后应用rownum。

最小化查询执行时间的解决方案是什么?

例如:

select * 
from 
    (select 
         acc_no, address 
     from 
         customer 
     order by 
         acc_no desc) 
where 
    ROWNUM <= 100;   

4 个答案:

答案 0 :(得分:2)

根据以往的经验,我发现TOP最适合这种情况。

此外,您应始终选择所需的列,并避免使用全卡(*)

@Override
public void onBindViewHolder(PlantViewHolder holder, int position) {
    holder.plantName.setText(plants.get(position).getSpecie());
    holder.plantCheck.setText("Are you sure this is the plant?");
}

有关TOP,LIMIT甚至ROWNUM的有用资源。

答案 1 :(得分:0)

确保在acc_no列上使用索引。

  1. 如果acc_no上已有索引,请通过验证查询执行计划来检查是否在查询执行期间使用了索引。
  2. 要创建新索引(如果不存在),请使用以下查询:

    Create index idx1 on customer(acc_no); -- If acc_no is not unique
    Create unique index idx1 on customer(acc_no); -- If acc_no is unique. Note: Unique index is faster.
    
    1. 如果在解释计划输出中看到“全表扫描”,那么优化程序不使用索引。
    2. 首先尝试使用提示:

      select /*+ index(idx1) */ * from 
      (select 
           acc_no, address 
       from 
           customer 
       order by 
           acc_no desc) 
      where 
      ROWNUM <= 100;   
      
      1. 如果带有上述提示的查询很快返回结果,那么您需要检查优化器为什么故意忽略您的索引。一个可能的原因是过时的统计数据。刷新统计信息。
      2. 希望这有帮助。

答案 2 :(得分:0)

考虑在内部查询/内嵌视图中获取您的最高帐号,以便您只对这100个客户记录执行连接。否则,您可以在百万行上执行所有连接,然后对百万+结果进行排序以获得前100个。这样的事情可能会有效。

    select .....
    from customer
    where customer.acc_no in (select acc_no from
                        (select inner_cust.acc_no
                         from   customer inner_cust
                         order by inner_cust.acc_no desc
                        )
                    where rownum <= 100)
       and ...

或者,如果您使用的是12C,则可以使用FETCH FIRST 100 ROWS ONLY

    select .....
    from customer
    where customer.acc_no in (select inner_cust.acc_no
                              from   customer inner_cust
                              order by inner_cust.acc_no desc
                              fetch first 100 rows only
                            )
       and ...

答案 3 :(得分:0)

这将在100ms内给出结果,但确保列ACC_NO上有索引。 ACC_NO +其他列上也可以有组合索引,但ACC_NO必须位于索引的第一个位置。您必须在执行计划中看到“范围扫描”。不是“全表扫描”,不是“跳过扫描”。您可以在执行计划中看到嵌套循环(将从表中获取ADDRESS)。您可以通过为ACC_NO,ADDRESS(按此顺序)创建组合索引来进一步提高速度。在这种情况下,Oracle引擎根本不必读取表,因为所有信息都包含在索引中。您可以在执行计划中进行比较。

select top 100 acc_no, address 
    from customer 
    order by acc_no desc