选择查询的不同列会产生不同的成本

时间:2013-08-27 08:40:12

标签: performance oracle indexing

invt_item_d列上的表(item_id & branch_id & co_id)上有一个索引。 第一个查询的计划结果为TABLE ACCESS FULL,费用为528, 第二个查询的结果为INDEX FAST FULL SCAN(我的索引),费用为27

唯一的区别是,如您所见,所选列在第二个查询的索引中使用。

这有什么问题吗?请问,您能告诉我应该怎么做才能在db管理级别修复此问题?

select d.qty
  from invt_item_d d 
 where d.item_id = 999 
   and d.branch_id = 888 
   and d.co_id = 777

select d.item_id
  from invt_item_d d 
 where d.item_id = 999 
   and d.branch_id = 888 
   and d.co_id = 777

编辑: 我做了一个新的查询,这个查询的成本是529,其中TABLE ACCESS FULL。

select qty from invt_item_d

所以我是否使用索引并不重要。有人说这是正常的,这真的是一种正常行为吗?

3 个答案:

答案 0 :(得分:1)

在第一种情况下,必须访问该表,因为“qty”列仅存储在表中。

在第二种情况下,可以从索引中读取查询中使用的所有列,跳过完全读取的表。

您可以在列上添加另一个索引(item_id,branch_id,co_id,qty),它很可能会在第一个查询中使用。

来自Oracle文档:http://docs.oracle.com/cd/E11882_01/server.112/e25789/indexiot.htm

  

快速完整索引扫描是数据库中的完整索引扫描   访问索引本身的数据而不访问表,和   数据库没有特定的顺序读取索引块。

     

快速完整索引扫描是全表扫描的替代方法   满足以下两个条件:

     
      
  • 索引必须包含查询所需的所有列。

  •   
  • 包含所有空值的行不得出现在查询结果集中。为了保证这个结果,至少有一列   index必须具有:

         
        
    • NOT NULL约束

    •   
    • 应用于它的谓词可防止在查询结果集中考虑空值

    •   
  •   

答案 1 :(得分:0)

这正是使用索引的主要目的 - 让搜索速度更快。 与查询没有索引的列相比,查询具有索引的列更快。

它的基本知识。

答案 2 :(得分:0)

我正在添加另一个答案,因为它似乎更方便。

第一: “我没有点击索引,因为有34000行,而不是数百万”。这完全是错误的并且是一种危险的理解。

我的意思是,如果有几千行,并且没有命中索引(oracle引擎执行全表扫描(表ACCESS FULL)),那不是什么大不了的事。 Oracle足够快,可以在几秒钟内读取几千行(即使没有索引),因此您不会感觉到差异。查询仍然较慢(比有索引时),但它是如此微小慢一点,你不会感觉到差异。 但是,如果有数百万行,那么在没有索引的情况下查询的执行速度会慢得多(因为这次它将在全表扫描中扫描数百万行)并且您的性能将受到影响。

第二:为什么你要在34000行的表上循环,那也是4000次? 这是一个可怕的方法。尽可能避免循环。必须有更好的方法!

第三: 您可以使用索引提示强制oracle优化器命中索引。您需要知道索引的名称。

select /*+ index(invt_item_d <index_name>) */
       d.qty
  from invt_item_d d 
 where d.item_id = 999 
   and d.branch_id = 888 
   and d.co_id = 777

以下是关于索引提示的堆栈溢出问题的link