2011-06-10 91 views
4

你好我有一个SQL查询,我试图优化。这个查询在0.3秒内完成,但我需要为吨的不同storeIds运行相同的查询 - 无论如何要优化此查询以使其更快,或者更改它以便一次获得所有storeIds。优化Oracle SQL查询

我总是可以在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是不唯一的,分区,NO JOIN_INDEX 所有其他的列是唯一的,分区,NO JOIN_INDEX

+0

你是什么意思“所有其他列都是唯一的”?每一列都是独一无二的(我认为不是)?或者,除了pid外,还有一个涵盖所有列的唯一索引?或者是其他东西?如果有多列索引,那么每个索引中的列顺序是什么?索引是分区的,也是表格吗?当前查询的执行计划是什么? – 2011-06-10 22:42:09

+0

你能发布实际执行计划吗?您可以使用DBMS_XPLAN获取它。 – eaolson 2011-06-11 00:53:30

+0

另外,您使用的是哪个版本的Oracle? – 2011-06-11 04:43:39

回答

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 

衡量它看看。

+1

charlie,1989年打电话给他们想让他们隐式的'where'加入回来。 – Johan 2011-06-10 21:04:11

+1

@Johan:将连接转换为JOIN ON语法留给读者的练习:) – 2011-06-10 21:07:52

+0

这是原始查询,它要慢得多。 – Overload119 2011-06-10 21:10:25

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生成一个糟糕的查询计划时,底层的统计数据会误导优化器,如果是这样的话,那么修复统计信息要比提示查询要好得多

1

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

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

更改查询以获得“所有的storeids一次”很简单 - 完全删除storeid上的条件。如果实际上需要每个可能的storeid的结果,那么通过对每个块运行一个查询,您很可能会浪费大量时间重复访问块。但是,也许通过“所有的装备”你意味着所有的一小组ID。

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 

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