是否有任何数据库服务器可以优化以下查询?

时间:2011-02-25 18:43:12

标签: sql query-optimization


假设我有表my_table(id int not null primary key, datafield varchar(100))。询问 SELECT * from my_table where id = 100执行索引搜索。如果我将其更改为

SELECT * from my_table where id+1 = 101

它扫描整个索引(索引扫描)(至少它在SQL Server和Mysql中执行)。是否有任何数据库服务器“理解”id +1 = 101id = 101-1相同?我确实意识到这不是一个典型的数据库操作,服务器在这种情况下不必执行任何数学运算,但我想知道它是否在任何地方实现?

感谢
更新
到目前为止,我已经尝试过SQL Server 2008 Enterprise,Mysql 5.1,5.5。 SQL Server分别显示聚簇索引查找和聚簇索引扫描。 Mysql explain显示ref:const, key:primary, rows:1ref:null, key:null,rows: #total number of rows in the table

4 个答案:

答案 0 :(得分:2)

  

id +1 = 101与id = 101-1相同

不,不是。如果+1溢出id会怎么样?

答案 1 :(得分:1)

我尝试使用PostgreSQL 9.0,除非我在(id - 1)创建一个索引,否则它不会使用索引。

所以使用以下索引定义

create index idx_minus on my_table ( (id - 1) );

PostgreSQL使用查询索引

select *
from my_table
where id - 1 = 12345

答案 2 :(得分:1)

有趣。

您可以将Oracle Release 10.2.0.1.0添加到列表中(无法重写查询)。

create table t(
   id
  ,x
  ,padding
  ,primary key (id)
) as
select rownum              as id
      ,'x'                 as x
      ,lpad('x', 100, 'x') as padding
  from dual
 connect by level <= 50000;

查询1。

select id
  from t
 where id = 100 + 1;

----------------------------------------+
| Id  | Operation         | Name        |
-----------------------------------------
|   0 | SELECT STATEMENT  |             |
|*  1 |  INDEX UNIQUE SCAN| SYS_C006659 |
-----------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------    
   1 - access("ID"=101)

查询2.

select id
  from t
 where id + 1 = 101;

--------------------------------------------
| Id  | Operation            | Name        |
--------------------------------------------
|   0 | SELECT STATEMENT     |             |
|*  1 |  INDEX FAST FULL SCAN| SYS_C006659 |
--------------------------------------------    

Predicate Information (identified by operation id):
---------------------------------------------------    
   1 - filter("ID"+1=101)

查询3.

select x
  from t
 where id + 1 = 101;

------------------------------------------
| Id  | Operation         | Name | Rows  |
------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |
|*  1 |  TABLE ACCESS FULL| T    |     1 |
------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------    
   1 - filter("ID"+1=101)

答案 3 :(得分:0)

为什么不这样做呢(假设您不希望服务器进行数学运算来计算您正在寻找的实际ID)?

SELECT * FROM my_table WHERE id = (101 - 1)