2013-03-23 72 views
3

您有一列字符串foo,該字段類型爲該列的索引。你想從表SELECT的表WHEREfoo列有前綴'pre'。顯然,該指數應該能夠在這裏幫助。使用索引按字符串前綴進行選擇

這裏是由前綴搜索的最明顯的方式:

SELECT * FROM tab WHERE foo LIKE 'pre%'; 

不幸的是,這並沒有得到優化使用索引(在Oracle或Postgres的,至少)。

以下,然而,確實工作:

SELECT * FROM tab WHERE 'pre' <= foo AND foo < 'prf'; 

但是否有更好的方法來做到這一點,還是有使上述更優雅的方式?特別是:

  • 我需要從'pre''prf'的功能,但是這對於任何潛在的整理工作。而且,它比上面更復雜,因爲如果搜索例如'prz'那麼上限必須是'psa',依此類推。
  • 我可以抽象成一個存儲的函數/過程,仍然打索引?所以我可以寫一些像... WHERE prefix('pre', foo);

解答所有DBMSes讚賞。

+0

什麼?不幸的是,這'這會得到優化使用索引'?這件事很糟糕嗎?當然,如果可能的話,'開始'搜索使用索引。感謝上帝,它確實。 ....我誤解了你嗎? – alzaimar 2013-03-23 22:20:16

+0

哈哈,對不起,我不小心這個詞「不」!編輯 – jameshfisher 2013-03-23 22:33:34

+0

哦,你的意思是在SQL中有一個「開始」構造?我找不到任何關於此的信息。 – jameshfisher 2013-03-23 22:36:17

回答

0

數據庫在這裏非常重要。恰巧SQL Server對like進行了這種優化。

一種方法是做這樣的事情:

where foo >= 'pre' and foo <= 'pre+'~' 

「〜」有一個可打印字符的最大的7位ASCII值,所以它基本上是比什麼都大。但是,如果使用寬字符或非標準字符集,則可能會出現問題。

你不能將這個抽象成一個函數,因爲使用函數通常會排除索引的使用。如果您總是查看前三個字符,那麼在Oracle中,您可以在這三個字符(稱爲「基於函數的索引」)上創建索引。

+0

我不認爲'foo <='pre〜'是有效的,因爲它會刪除像'pre〜fix'這樣的值。如果使用'<='比較,那麼值必須是'pre ~~~~~~~~~ ...'進行永久。 使用功能:我認爲你是對的。也許SQL中的宏將是一件好事,但那是天空中的餡餅。 – jameshfisher 2013-03-23 23:11:55

-3

如何

select * from tab where foo between 'pre' and 'prf' and foo != 'prf' 

這使得指數相同。 RDBMS必須非常笨而不是使用該索引。

+0

您使用包含範圍的結束範圍,那麼必須指定另一個條件才能使結束排除?爲什麼不'foo> ='pre'和foo <'prf''? – ErikE 2013-03-23 23:13:35

+0

不錯的問題。我沒有嘗試過,但是從我的膽量來看,似乎「間」更好。嗯...我相信我應該更多地進入證據嗎? – alzaimar 2013-03-23 23:24:43

+0

對於'l <= x AND x <= h',x和h'不僅僅是糖嗎? – jameshfisher 2013-03-23 23:49:32