从选择,性能中选择

时间:2018-01-25 21:46:22

标签: sql oracle performance

我想问一下,哪种查询应该更有效率?

select col1, col2 from 
    (select col1, col2 from table2) 
where col1 = 'something'

select col1, col2 from 
    (select col1, col2 from table2 
    where col1 = 'something') 
where col1 = 'something'

似乎第二个查询应该更有效但在sqldeveloper第一个查询需要更少的时间。为什么会那样?

2 个答案:

答案 0 :(得分:2)

以下表格的一个小例子:

create table tab1(col1, col2) as
select level, case when mod(level, 2) = 0 then 'even' else 'odd' end
from dual
connect by level < 100000;

create table tab2(col1, col2) as
select level, case when mod(level, 2) = 0 then 'even' else 'odd' end
from dual
connect by level < 100000;

第一个查询

select col1, col2
from (
      select col1, col2
      from tab1
     )
where col2 = 'odd';

有计划:

----------------------------------
| Id  | Operation         | Name |
----------------------------------
|   0 | SELECT STATEMENT  |      |
|   1 |  TABLE ACCESS FULL| TAB1 |
----------------------------------

和第二个查询

select col1, col2
from
    (
     select col1, col2
     from tab2
     where col2 = 'odd'
    )
where col2 = 'odd';

具有

----------------------------------
| Id  | Operation         | Name |
----------------------------------
|   0 | SELECT STATEMENT  |      |
|   1 |  TABLE ACCESS FULL| TAB2 |
----------------------------------

两个查询都有相同的计划。

如果我添加索引:

create index tab1_idx on tab1(col2);
create index tab2_idx on tab2(col2);

查询仍有相同的计划:

------------------------------------------------
| Id  | Operation                   | Name     |
------------------------------------------------
|   0 | SELECT STATEMENT            |          |
|   1 |  TABLE ACCESS BY INDEX ROWID| TAB1     |
|   2 |   INDEX RANGE SCAN          | TAB1_IDX |
------------------------------------------------

------------------------------------------------
| Id  | Operation                   | Name     |
------------------------------------------------
|   0 | SELECT STATEMENT            |          |
|   1 |  TABLE ACCESS BY INDEX ROWID| TAB2     |
|   2 |   INDEX RANGE SCAN          | TAB2_IDX |
------------------------------------------------

请注意,简单地运行两个查询可能不是检查其性能的好方法,因为Oracle可能会缓存第一个查询的结果,因此在第二个查询中会更快。

解释计划对于查询实际执行的内容以及它如何扫描表和索引非常有用。

答案 1 :(得分:1)

容易相互转化的查询通常效率相同。

Oracle不必按照编写顺序运行查询。 Oracle优化器可以像大多数程序员一样重新安排条件,删除括号,消除冗余条件,以及执行其他查询转换。对于具体的例子,Google&#34;谓词推送&#34;和&#34;查看合并&#34;。

除非您的示例中有更多内容,否则这两个查询应该同时运行。

如果他们不这样做,那很可能是一个测试错误。由于缓存和服务器负载,测量查询性能可能很棘手。

如果缓存没有解释,请查看完整的解释计划,包括&#34; Notes&#34;部分。两个不同的查询运行方式不同的另一个原因是因为其中一个查询可能有计划管理。例如,DBA可能已经专门为一个查询添加了一个SQL配置文件来修复某些问题。并且更改单个空间可以使查询与SQL配置文件不再适用的位置不同。