Sql 从中选择,选择性能

Sql 从中选择,选择性能,sql,oracle,performance,Sql,Oracle,Performance,我想问,什么查询应该更有效 select col1, col2 from (select col1, col2 from table2) where col1 = 'something' 或 看起来第二个查询应该更有效,但在sqldeveloper中,第一个查询花费的时间更少。为什么会这样?下面是一个小例子: create table tab1(col1, col2) as select level, case when mod(level, 2) = 0 then 'even'

我想问,什么查询应该更有效

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


看起来第二个查询应该更有效,但在sqldeveloper中,第一个查询花费的时间更少。为什么会这样?

下面是一个小例子:

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;
该计划是否:

----------------------------------
| 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';

两个查询具有相同的计划

如果我添加索引:

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可能会缓存第一个查询的结果,从而在第二个查询中运行得更快


explain计划有助于了解查询的真正功能以及它如何扫描表和索引。

容易相互转换的查询通常同样有效

Oracle不必按照编写查询的顺序运行查询。Oracle optimizer可以像大多数程序员一样重新安排条件、删除括号、消除冗余条件以及执行其他查询转换。对于具体的例子,谷歌的“谓词推送”和“视图合并”

除非示例中还有其他内容,否则这两个查询应该同时运行


如果他们没有,很可能是测试错误。由于缓存和服务器负载,测量查询性能可能很棘手


如果缓存不能解释它,请查看完整的解释计划,包括“注释”部分。两个完全不同的查询运行方式不同的另一个原因是其中一个可能有计划管理。例如,DBA可能专门在一个查询中添加了一个SQL配置文件来修复某些问题。更改单个空格会使查询变得足够不同,以致SQL配置文件不再适用。

两个查询都会失败。请不要使用不适用于您的问题的标记。您不必在第二个查询中按Col1 twince进行筛选。Col1='something'的行已在子查询中筛选。为什么您认为第二个查询应该更有效?您正在向混合中添加另一个过滤器。和一个正在筛选已筛选记录的。在您给定的示例中,
从表2中选择col1,col2,其中col1='something'
处理的步骤更少。@johncode-您编辑了标记以删除
[sql server]
[mysql]
,但离开了
[oracle]
。你为什么选择这个?从OP历史记录中的问题来看,他们更可能使用的是
[mysql]
(Oracle SQL Developer可以连接到mysql,并安装正确的JDBC jar)。“这很可能是一个测试错误”*。阿门。性能测试尤其难以正确进行。
----------------------------------
| 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 |
------------------------------------------------