2013-05-18 79 views
-1
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优化器执行查询

这是否意味着Oracle正在使用索引来执行此查询?

+0

'PURCHASENO'是一个主键,它有一个唯一索引,所以是的 - oracle选择一个索引访问路径。 – haki

+0

“INDEX UNIQUE SCAN”不是一个线索吗?你看过[性能调整指南](http://docs.oracle.com/cd/E29597_01/server.1111/e16638/optimops.htm#i82029)吗? –

+0

@AlexPoole是的,我只是想确保为了完全回答这个问题。 – Jim

回答

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来挑出行的其余部分。您注意到字节的列有46个,这意味着该行的长度是46个字节。

是你,而不是使用下面的查询将不再需要通过ROWID访问:

select purchaseno 
    from purchase 
where purchaseno = 1000 

这是因为列PURCHASENO已经在指数;没有必要访问表格。因此,select *被认为是“有害的”,不仅增加了您必须从磁盘读取的数据量以及可能需要通过网络发送的数据量,还意味着您可能需要额外执行操作以访问您的数据。只有选择你需要的行。

最后两点,在您的查询中,值PUCRHASENO被括在引号中,尽管是一个数字。如果PURCHASENO实际上是一个角色,那么这很好,但如果这是一个数字,那么您就会冒险将这些角色转换为数字。甲骨文explicitly recommends against implicit conversion,原因如下:

  • SQL语句是容易当你使用显式数据类型转换函数理解。

  • 隐式数据类型转换可能会对性能产生负面影响,尤其是如果将列值的数据类型转换为常数而非其他方式。

  • 隐式转换取决于它发生的上下文,并且在每种情况下可能不会以相同的方式工作。例如,从日期时间值到VARCHAR2值的隐式转换可能会返回意外的一年,具体取决于NLS_DATE_FORMAT 参数的值。

  • 隐式转换的算法可能会在软件版本和Oracle产品之间发生变化。显式转换的行为更具可预测性。

这样做可以混淆优化不够,你使用索引,虽然这是不太可能和你的一样简单查询的情况发生。

最后,这是个人偏好,我发现PURCHASE表的主键的名称相当混乱。一个更好的标准是PK_<table name>而不是PK_<column name>一个表只能有一个主键,并且只有一个该名称的对象可以在任何一个模式中。但是,可能有两个表的列名与主键相同。

Oracle性能调优指南中有关于reading and understanding explain plans的一章,我强烈建议阅读。

+0

非常感谢 – Jim