今天在讀一篇關於資料庫索引介紹的文章時,該文章提到了字首索引,對於我這個搞資料庫應用開發那麼多年的人來說,這個詞還真是乙個新詞,沒用過。於是打算研究一番。
字首索引似乎是mysql中的乙個概念,在sql server和oracle中沒提出這個概念。於是就安裝了乙個mysql來做實驗,搞清楚字首索引。
字首索引說白了就是對文字的前幾個字元(具體是幾個字元在建立索引時指定)建立索引,這樣建立起來的索引更小,所以查詢更快。有點相當於oracle中對字段使用left函式,建立函式索引,只不過mysql的這個字首索引在查詢時是內部自動完成匹配的,並不需要使用left函式。
mysql 字首索引能有效減小索引檔案的大小,提高索引的速度。但是字首索引也有它的壞處:mysql 不能在 order by 或 group by 中使用字首索引,也不能把它們用作覆蓋索引(covering index)。
建立字首索引的語法為:
alter
table
table_name
add
key(
column_name
(prefix_length))
; 這裡最關鍵的引數就是prefix_length,這個值需要根據實際表的內容,得到合適的索引選擇性(index selectivity)。索引選擇性就是不重複的個數與總個數的比值。
select
1.0*
count(
distinct column_name)
/count(
*)from table_name
比如我們現在有個employee表,其中有個firstname欄位,是varchar(50)的,我們查詢該字段的索引選擇性:
select
1.0*
count(
distinct firstname)
/count(
*)from employee
得到結果0.7500,然後我們希望對firstname建立字首索引,希望字首索引的選擇性能夠盡量貼近於對整個字段建立索引時的選擇性。我們先看看3個字元,如何:
select
1.0*
count(
distinct
left(firstname,
3))/
count(
*)from employee
得到的結果是0.58784,好像差距有點大,我們再試一試4個字元呢:
select
1.0*
count(
distinct
left(firstname,
4))/
count(
*)from employee
得到0.68919,已經提公升了很多,再試一試5個字元,得到的結果是0.72297,這個結果與0.75已經很接近了,所以我們這裡認為字首長度5是乙個合適的取值。所以我們可以為firstname建立字首索引:
alter
table test.employee
addkey(firstname(
5))
建立字首索引後查詢語句並不需要更改,如果我們要查詢所有firstname為devin的employee,那麼sql仍然寫成:
select
*from employee e
where e.firstname
='devin
';
下面總結一下什麼情況下使用字首索引:
字首索引,一種優化索引大小的解決方案
今天在讀一篇關於資料庫索引介紹的文章時,該文章提到了字首索引,對於我這個搞資料庫應用開發那麼多年的人來說,這個詞還真是乙個新詞,沒用過。於是打算研究一番。字首索引似乎是mysql中的乙個概念,在sql server和oracle中沒提出這個概念。於是就安裝了乙個mysql來做實驗,搞清楚字首索引。字...
建立索引遇見ORA 00054 的一種解決方案
create index idx test on t1 x online nologging parallel 4 當建立索引時候遇見如下錯誤,ora 00054 資源正忙,但指定以 nowait 方式獲取資源,或者超時失效 可以先執行下 aler session set ddl lock time...
Sphinx(一種全文檢索引擎)
簡介編輯 sphinx是乙個基於sql的 全文檢索引擎,可以結合mysql,postgresql做 全文搜尋,它可以提供比資料庫本身更專業的搜尋功能,使得 應用程式更容易實現專業化的全文檢索。sphinx特別為一些 指令碼語言設計搜尋api介面,如php,python,perl,ruby等,同時為m...