PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2822030489
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 46 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| PURCHASE | 1 | 46 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | PK_PURCHASENO | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("PURCHASENO"=9989)
14 rows selected.
有人可以向我解释这意味着什么吗?
这是否意味着Oracle正在使用索引来执行此查询?
答案 0 :(得分:1)
线索在计划中。
这意味着您可以独特地扫描索引PK_PURCHASENO。
| Operation | Name | Rows |
---------------------------------------------
| INDEX UNIQUE SCAN | PK_PURCHASENO | 1 |
我假设这个名字是你的主键,并且根据你的查询判断它是在PURCHASENO列上。主键必须是唯一的,所以这并不奇怪。您注意到行列表示您只返回一行,这确认了这一点.a
另一个重要的是这一行。
| Id | Operation | Name | Rows | Bytes |
---------------------------------------------------------------------
| 1 | TABLE ACCESS BY INDEX ROWID| PURCHASE | 1 | 46 |
您已对索引进行了唯一扫描,但您不仅仅是从索引中选择数据,还必须在编写select *
时从表中返回数据。 ROWID是表中标识行的唯一地址。通过它的ROWID访问(单个)行是返回数据的最快方法。 Oracle在主键索引中找到所需的行,然后使用rowid选择行的其余部分。您注意到 bytes 列有46,这意味着该行的长度为46个字节。
相反,如果您使用以下查询,则不再需要ROWID访问:
select purchaseno
from purchase
where purchaseno = 1000
这是因为PURCHASENO列已经在索引中;没有必要访问该表。 select *
被认为是“有害的”,因为这样做不仅会增加您从磁盘读取的数据量,还可能增加您通过网络发送的数据量,但这也意味着您可能必须执行其他操作才能访问您的数据。只能选择你需要的行。
最后两点,在您的查询中,值PUCRHASENO用引号括起来,尽管它是一个数字。如果PURCHASENO实际上是一个角色,这很好,但是如果它是一个数字,你在这里冒险,因为你隐含地将角色转换为数字。 Oracle explicitly recommends against implicit conversion的原因如下:
使用显式数据类型转换函数时,SQL语句更容易理解。
隐式数据类型转换可能会对性能产生负面影响,尤其是当列值的数据类型转换为常量的数据类型而不是相反时。
隐式转换取决于它发生的上下文,并且在每种情况下可能无法以相同的方式工作。例如,从datetime值到VARCHAR2值的隐式转换可能会返回意外的年份,具体取决于NLS_DATE_FORMAT的值 参数。
隐式转换的算法可能会在软件版本和Oracle产品之间发生变化。显式转换的行为更具可预测性。
执行此可能会使优化程序混淆,以至于不使用索引,尽管这在查询中不太可能像您那样简单。
最后,这是个人偏好,我发现PURCHASE表的主键名称相当混乱。更好的标准是PK_<table name>
而不是PK_<column name>
一个表只能有一个主键,并且该名称中只有一个对象可以在任何一个模式中。但是,可以使两个表具有与主键相同的列名。
Oracle性能调优指南有一章reading and understanding explain plans,我强烈建议您阅读。