2011-02-25 53 views
1


比方說,我有表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相同的數據庫服務器?我意識到這不是一個典型的數據庫操作,並且服務器在這種情況下不需要執行任何數學操作,但是我想知道它是否在任何地方實現?

感謝
UPDATE
到目前爲止,我已經試過SQL Server 2008企業版,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

+1

是你能肯定,只要用SQL 2008 R2和測試這兩種情況只做索引查找,而不是表掃描,你嘗試過哪些版本它與? – 2011-02-25 18:51:10

+0

@ K Ivanov:我剛剛嘗試過一次:1.Clustered index seek; 2.聚簇索引掃描。對不起,在我的問題中,它應該說「掃描整個索引」而不是「整個表」。我會改變它。 +1指向它 – a1ex07 2011-02-25 19:01:53

回答

2

ID 1 = 101是相同的ID = 101-1

否它不是。如果+1溢出ID,該怎麼辦?

+0

你可能是正確的溢出,我不確定關於sql表達式的提升規則,但是,例如,'id + 0 = 100'不能溢出,可以嗎? – a1ex07 2011-02-25 20:01:56

+0

你會編寫代碼來尋找某人將0字面值添加到希望優化該情況的東西嗎?這種優化是否有助於產生這個問題的情況? – 2011-02-25 20:46:20

+0

好吧,我同意'+ 0'沒有多大意義。我仍然不確定是否不可能提前發現可能的溢出/下溢,如果這是不這樣做的唯一原因。無論如何,謝謝你的好處。 +1。 – a1ex07 2011-02-25 22:08:34

0

爲什麼不只是這樣做呢(假設您不希望服務器計算您正在查找的實際ID)?

SELECT * FROM my_table WHERE id = (101 - 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 
+0

感謝您的信息,很高興知道。但是,這可能意味着如果我將'where id-1 = 12345'改爲'where id -2 = 12345',我應該創建另一個索引? – a1ex07 2011-02-25 19:55:02

+0

@ a1ex07:是的,這是正確的。所以如果你的「+值」隨着每個查詢而改變,你將無法創建合適的索引。 – 2011-02-25 20:50:04

+0

@ a1ex07 - 我在SQL Server的索引持久列中試過這個,它沒有被使用,除非我實際上通過名稱來選擇列。不確定企業版是否會取而代之。TBH我認爲這對於SQL Server開發人員來說,將會完全浪費開發時間來實現會重寫這樣的謂詞。我寧願他們繼續處理更重要的問題,比如實施「OVER」條款。 – 2011-02-25 23:45:36

1

有趣。

您可以將Oracle版本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) 
+0

感謝您花時間嘗試。 +1 – a1ex07 2011-02-25 23:55:58