Есть ли сервер БД, который может оптимизировать следующий запрос? - PullRequest
1 голос
/ 25 февраля 2011


Допустим, у меня есть таблица 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 = 101 совпадает с id = 101-1?Я понимаю, что это не типичная операция с базой данных, и серверу не нужно выполнять какую-либо математику в таких случаях, но мне интересно, реализована ли она где-нибудь?
До сих пор я пробовал SQL Server 2008 Enterprise, Mysql 5.1, 5.5.SQL Server показывает поиск кластеризованного индекса и сканирование кластерного индекса соответственно.Mysql explain показывает ref:const, key:primary, rows:1 и ref:null, key:null,rows: #total number of rows in the table

Ответы [ 4 ]

2 голосов
/ 25 февраля 2011

id +1 = 101 - это то же самое, что id = 101-1

Нет, это не так.Что если +1 переполняет идентификатор?

1 голос
/ 26 февраля 2011

Интересно.

Вы можете добавить 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)
1 голос
/ 25 февраля 2011

Я пробовал это с PostgreSQL 9.0, и он не использует индекс, если я не создаю его на (id - 1).

То есть со следующим определением индекса

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

PostgreSQL использует индекс для запроса

select *
from my_table
where id - 1 = 12345
0 голосов
/ 25 февраля 2011

Почему бы просто не сделать это вместо этого (при условии, что вы не хотите, чтобы сервер вычислял фактический идентификатор, который вы ищете)?

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