索引的建立與設計原則

2022-09-20 13:51:11 字數 4791 閱讀 4048

mysql的索引包括普通索引、唯一性索引、全文索引、單列索引、多列索引和空間索引等。

● 從功能邏輯上說,索引主要有4種,分別是普通索引、唯一索引、主鍵索引、全文索引。

● 按照物理實現方式,索引可以分為2種:聚簇索引和非聚簇索引。

● 按照作用字段個數進行劃分,分成單列索引和聯合索引。

1、普通索引

在建立普通索引時,不附加任何限制條件,只是用於提高查詢效率。這類索引可以建立在任何資料型別中,其值是否唯一和非空,要由字段本身的完整性約束條件決定。建立索引以後,可以通過索引進行查詢。例如,在表student的字段name上建立乙個普通索引,查詢記錄時就可以根據該索引進行查詢。

2、唯一性索引

使用unique引數可以設定索引為唯一性索引,在建立唯一性索引時,限制該索引的值必須是唯一的,但允許有空值。在一張資料表裡可以有多個唯一索引。

3、主鍵索引

主鍵索引就是一種特殊的唯一性索引,在唯一索引的基礎上增加了不為空的約束,也就是notnulla+unique,一張表裡最多只有乙個主鍵索引。

4、單列索引

在表中的單個欄位上建立索引。單列索引只根據該欄位進行索引。單列索引可以是普通索引,也可以是唯一性索引,還可以是全文索引。只要保證該索引只對應乙個字段即可。乙個表可以有多個單列索引。

5、多列(組合、聯合)索引

多列索引是在表的多個字段組合上建立乙個索引。該索引指向建立時對應的多個字段,可以通過這幾個字段進行查詢,但是只有查詢條件中使用了這些欄位中的第乙個欄位時才會被使用。例如,在表中的字段id、name和gender上建立乙個多列索引idx_id_name_gender,只有在查詢條件中使用了字段id時該索引才會被使用。使用組合索引時遵循最左字首集合

6、全文索引

使用引數fulltext可以設定索引為全文索引。在定義索引的列上支援值的全文查詢,允許在這些索引列中插入重複值和空值。全文索引只能建立在charvarchartext型別及其系列型別的字段上,查詢資料量較大的字串型別的字段時,使用全文索引可以提高查詢速度。例如,表student的字段informationtext型別,該欄位包含了很多文字資訊。在字段information上建立全文索引後,可以提高查詢欄位information的速度。

全文索引典型的有兩種型別:自然語言的全文索引和布林全文索引。

7、補充:空間索引

使用引數spatial可以設定索引為空間索引。空間索引只能建立在空間資料型別上,這樣可以提高系統獲取空間資料的效率。mysql中的空間資料型別包括geometrypointlinestringpolygon等。目前只有mylsam儲存引擎支援空間檢索,而且索引的字段不能為空值。對於初學者來說,這類索引很少會用到。

小結:不同的儲存引擎支援的索引型別也不一樣

innodb:支援 b-tree、full-text等索引,不支援hash索引;

mylsam:支援b-tree、full-text等索引,不支援hash索引;

memory :支援b-tree、hash等索引,不支援full-text索引;

ndb:支援hash索引,不支援b-tree、full-text等索引;

archive :不支援b-tree、hash、full-text等索引;

降序索引以降序儲存鍵值。雖然在語法上,從mysql 4版本開始就已經支援降序索引的語法了,但實際上該desc定義是被忽略的,直到mysql 8.x版本才開始真正支援降序索引(僅限於innodb儲存引擎)。

mysql在8.0版本之前建立的仍然是公升序索引,使用時進行反向掃瞄,這大大降低了資料庫的效率。在某些場景下,降序索引意義重大。例如,如果乙個查詢,需要對多個列進行排序,且順序要求不一致,那麼使用降序索引將會避免資料庫使用額外的檔案排序操作,從而提高效能。

舉例:分別在mysol 5.7版本和mysol 8.o版本中建立資料表ts1,結果如下:

create table ts1(a int, b intm index idx_a_b(a,b desc));
在mysql5,7版本中檢視資料表ts1的結構,結果如下:

從結果可以看出,索引仍然是預設的公升序。

在mysql8.0版本中檢視資料庫表ts1的結構,結果如下:

從結果可以看出,索引已經是降序了。下面繼續測試降序索引在執行計畫中的表現。

分別在mysql 5.7版本和mysql 8.0版本的資料表ts1中插入800條隨機資料,執行語句如下:

delimiter //

create procedure ts_insert()

begin

declare i int default 1;

while i <= 800

do insert into ts1 select rand()*80000, rand()*80000;

set i = i+1;

end while;

commit;

end//

delimiter;

# 呼叫

call ts_insert();

在mysql5.7版本中檢視資料庫表ts1的執行計畫,結果如下:

explain select * from ts1 order by a,b desc limit 5;
從結果可以看出,執行計畫中掃瞄數為799,而且使用了using filesort。

using filesort是mysql中一種速度比較慢的外部排序,能避免是最好的。多數情況下,管理員可以通過優化索引來盡量避免出現using filesort,從而提高資料庫執行速度。

在mysql 8.0版本中檢視資料表ts1的執行計畫。從結果可以看出,執行計畫中掃瞄數為5,而且沒有使用using filesort。

注意

降序索引只對查詢中特定的排序順序有效,如果使用不當,反而查詢效率更低。例如,上述查詢排序條件改為order by a desc, b desc,mysql 5.7的執行計畫要明顯好於mysql 8.0。

將排序條件修改為order by a desc, b desc後,下面來對比不同版本中執行計畫的效果。在mysql 5.7版本中檢視資料表ts1的執行計畫,結果如下:

explain select * from ts1 order by a desc, b desc limit 5;
在mysql 8.0版本中檢視資料表ts1的執行計畫。

從結果可以看出,修改後mysql 5.7的執行計畫要明顯好於mysql 8.0。

在mysql 5.7版本及之前,只能通過顯式的方式刪除索引。此時,如果發現刪除索引後出現錯誤,又只能通過顯式建立索引的方式將刪除的索引建立回來。如果資料表中的資料量非常大,或者資料表本身比較大,這種操作就會消耗系統過多的資源,操作成本非常高。

從mysql 8.x開始支援隱藏索引(invisible indexes),只需要將待刪除的索引設定為隱藏索引,使查詢優化器不再使用這個索引(即使使用force index(強制使用索引),優化器也不會使用該索引),確認將索引設定為隱藏索引後系統不受任何響應,就可以徹底刪除索引。這種通過先將索引設定為隱藏索引,再刪除索引的方式就是軟刪除

同時,如果你想驗證某個索引刪除之後的查詢效能影響,就可以暫時先隱藏該索引。

注意

主鍵不能被設定為隱藏索引。當表中沒有顯式主鍵時,表中第乙個唯一非空索引會成為隱式主鍵,也不能設定為隱藏索引。

1、建立表時直接建立在mysql中建立隱藏索引通過sql語句invisible來實現,其語法形式如下:

create table tablename(

propname1 type1[constraint1],

propname2 type2[constraint2],

....

....

index [indexname](propname1 [(length)]) invisible

);

上述語句比普通索引多了乙個關鍵字invisible,用來標記索引為不可見索引。

建立索引的原則 與 索引的分類

建立索引的原則 1 定義有主鍵的資料列一定要建立索引。因為主鍵可以加速定位到表中的某一行 2 定義有外間的資料列一定要建立索引。外來鍵列通常用於表與表之間的連線,在其上建立索引可以加快表間的連線。3 對於經常查詢的資料列最好建立索引。索引的分類 1 聚集索引 對錶和檢視進行物理排序,在表和檢視中只能...

索引建立的原則

索引查詢是資料庫中重要的記錄查詢方法,要不要進入索引以及在那些欄位上建立索引都要和實際資料庫系統的查詢要求結合來考慮,下面給出實際中的一些通用的原則 1.在經常用作過濾器的字段上建立索引 2.在sql語句中經常進行group by order by的字段上建立索引 3.在不同值較少的字段上不必要建立...

建立索引的原則

索引可以提高資料的訪問速度,但同時也增加了插入 更新和刪除操作的處理時間。所以是否要為表增加索引 索引建立在那些欄位上,是建立索引前必須要考慮的問題。解決此問題就是分析應用程式的業務處理 資料使用,為經常被用作查詢條件 或者被要求排序的字段建立索引。索引是建立在資料庫表中的某些列的上面。因此,在建立...