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
所以我是否使用索引并不重要。有人说这是正常的,这真的是一种正常行为吗?
答案 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