您好我有一个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
答案 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
尝试此查询必须花费更少的时间。