优化Oracle SQL查询

时间:2011-06-10 20:41:58

标签: sql oracle optimization

您好我有一个SQL查询,我正在尝试优化。此查询在0.3秒内完成,但我需要为大量不同的storeId运行相同的查询 - 无论如何都要优化此查询以使其更快,或者更改它以便它立即获取所有storeIds。

我总是可以在C#中创建一个新命令,该命令与命令连接,使其成为大量不同查询的联合。

select /*+ PUSH_SUBQ */ *  
from mytable r
where r.s in (1, 7)
and r.d in (1, 75)
and r.storeid = 1162
and r.period = 20110528
and r.pid in (select /*+ no_unnest qb_name(subq1) */ 
productid from otherTable where itmid=9999)

我已经尝试过这样的事情,但这需要永远。

select  /*+ PUSH_SUBQ */ * 
    from mytable r
    where r.s in (1, 7)
    and r.d in (1, 75)
    and r.storeid in (1162, 1223, 1231, 51231, 231, ...)
    and r.period = 20110528
    and r.pid in (select /*+ no_unnest qb_name(subq1) */ 
    productid from otherTable where itmid=9999)

MyTable有这样的索引: pid是NON-UNIQUE,PARTITIONED,NO JOIN_INDEX 所有其他列都是UNIQUE,PARTITIONED,NO JOIN_INDEX

5 个答案:

答案 0 :(得分:5)

尝试在查询中运行Oracle EXPLAIN PLAN。它应突出问题领域,并可能有助于缩小查询本身或被查询的表中的瓶颈。

使用EXPLAIN PLAN: http://download.oracle.com/docs/cd/B10500_01/server.920/a96533/ex_plan.htm

答案 1 :(得分:1)

如果你需要这个来运行许多不同的商店,你可能会指定一个不同StoreID值的列表,即

select *  
  from mytable r
 where r.s in (1, 7)
   and r.d in (1, 75)
   and r.storeid IN( 1162, 1163, 1164, ... )
   and r.period = 20110528
   and r.pid in (select productid 
                   from otherTable 
                  where itmid=9999)

如果要优化查询的性能,则需要提供两个表(MyTable和OtherTable)的结构,让我们知道两个表中存在哪些索引,并让我们对基数的基数有所了解。各种条件。

我会非常担心提示的存在(特别是PUSH_SUBQ提示会被忽略,因为它位于错误的位置。虽然为查询添加显式提示可能很少是合适和必要的,但它是几乎总是这样的情况,当Oracle生成一个糟糕的查询计划时,基础统计数据会误导优化器。如果是这样的话,那么修复统计数据要比提示查询要好得多。

答案 2 :(得分:1)

在没有看到执行计划和实际的索引/分区细节的情况下,我不知道建议什么来更快地执行查询。但是,在这种情况下,似乎解析时间可能很重要。您是否真的在样本中显示所有条件的文字值?你应该使用绑定变量;否则,您正在解析每个单独的查询,这不仅需要时间,还会造成瓶颈。

您可能希望运行扩展SQL跟踪,并手动读取跟踪或通过分析器运行它。

更改查询以“立即获取所有商品”很简单 - 完全删除storeid上的条件。如果您确实需要每个可能的storeid的结果,那么通过为每个storeid运行一个查询,您很可能会浪费大量时间反复访问块。但也许通过“所有的商品”你意味着所有一些小的ID。

答案 3 :(得分:0)

我的猜测是使用连接而不是子查询可能有所帮助。同时只选择您将使用的列:

select r.d, r.storeid, r.period, r.pid /* select only columns you need */
from mytable r, otherTable o
where r.s in (1, 7)
and r.d in (1, 75)
and r.storeid = 1162
and r.period = 20110528
and r.pid = o.productid /* use a join instead of subquery */
and o.itmid=9999

测量并查看。

答案 4 :(得分:0)

 select r.*  
  from mytable r 
   inner join otherTable o on r.pid = o.productid and o.itmid = 9999
  where r.s in (1, 7)
   and r.d in (1, 75)
   and r.storeid IN( 1162, 1163, 1164, ... )
   and r.period = 20110528

尝试此查询必须花费更少的时间。