1.SQL索引是什么?
定義:索引(Index)是幫助MySQL高效獲取數據的數據結構,就好比書的目錄,加快數據庫的查詢速度。
定義:索引(Index)是幫助MySQL高效獲取數據的數據結構,就好比書的目錄,加快數據庫的查詢速度。
2.SQL索引的作用是什么?優點是什么?
提高查詢效率
消除數據分組、排序
避免“回表”查詢(索引覆蓋)
優化聚合查詢
用於多表JOIN關聯查詢
利用唯一性約束,保證數據唯一性
InnDB行鎖實現
提高查詢效率
消除數據分組、排序
避免“回表”查詢(索引覆蓋)
優化聚合查詢
用於多表JOIN關聯查詢
利用唯一性約束,保證數據唯一性
InnDB行鎖實現
3.使用索引的優點
(1)可以通過建立唯一索引或者主鍵索引,保證數據庫表中每一行數據的唯一性.
(2)建立索引可以大大提高檢索的數據,以及減少表的檢索行數
(3)在表連接的連接條件 可以加速表與表直接的相連
(4)在分組和排序字句進行數據檢索,可以減少查詢時間中 分組 和 排序時所消耗的時間(數據庫的記錄會重新排序)
(5)建立索引,在查詢中使用索引 可以提高性能
(1)可以通過建立唯一索引或者主鍵索引,保證數據庫表中每一行數據的唯一性.
(2)建立索引可以大大提高檢索的數據,以及減少表的檢索行數
(3)在表連接的連接條件 可以加速表與表直接的相連
(4)在分組和排序字句進行數據檢索,可以減少查詢時間中 分組 和 排序時所消耗的時間(數據庫的記錄會重新排序)
(5)建立索引,在查詢中使用索引 可以提高性能
4.SQL索引的缺點是什么?
(1)增加I/O成本。在創建索引和維護索引 會耗費時間,隨着數據量的增加而增加
(2)增加磁盤空間。索引文件會占用物理空間,除了數據表需要占用物理空間之外,每一個索引還會占用一定的物理空間
(3)不合適的索引或索引過多,會降低增刪改的效率。.當對表的數據進行 INSERT,UPDATE,DELETE 的時候,索引也要動態的維護,這樣就會降低數據的維護速度,(建立索引會占用磁盤空間的索引文件。
一般情況這個問題不太嚴重,但如果你在一個大表上創建了多種組合索引,索引文件的會膨脹很快)。
(1)增加I/O成本。在創建索引和維護索引 會耗費時間,隨着數據量的增加而增加
(2)增加磁盤空間。索引文件會占用物理空間,除了數據表需要占用物理空間之外,每一個索引還會占用一定的物理空間
(3)不合適的索引或索引過多,會降低增刪改的效率。.當對表的數據進行 INSERT,UPDATE,DELETE 的時候,索引也要動態的維護,這樣就會降低數據的維護速度,(建立索引會占用磁盤空間的索引文件。
一般情況這個問題不太嚴重,但如果你在一個大表上創建了多種組合索引,索引文件的會膨脹很快)。
5.索引的分類?
(1)按存儲結構分類:
- BTREE:InnoDB & MyISAM
- HASH:HEAP,NDB,InnoDB AHI
- Fractal Tree:TokuDB
- RTREE
- FULLTEXT
(1)按存儲結構分類:
- BTREE:InnoDB & MyISAM
- HASH:HEAP,NDB,InnoDB AHI
- Fractal Tree:TokuDB
- RTREE
- FULLTEXT
(2)按數據的存儲方式(物理結構)分類:
- 聚集索引:聚簇索引的順序就是數據的物理存儲順序,索引與數據存放在同一個文件中。 (表中各行的物理順序與鍵值的邏輯(索引)順序相同,每個表只能有一個)
- 非聚集索引:非聚簇索引的順序與數據的物理存儲順序不同,索引與數據存放在不同的文件。 (非聚集索引指定表的邏輯順序。數據存儲在一個位置,索引存儲在另一個位置,索引中包含指向數據存儲位置的指針。可以有多個,小於249個)
(3)按應用層次分類:
(1)普通索引
最基本的索引,它沒有任何限制,用於加速查詢。
(2)唯一索引
索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。
(3)主鍵索引
是一種特殊的唯一索引,一個表只能有一個主鍵,不允許有空值。一般是在建表的時候同時創建主鍵索引。
(4)組合索引
指多個字段上創建的索引,只有在查詢條件中使用了創建索引時的第一個字段,索引才會被使用。使用組合索引時遵循最左前綴集合。
(5)全文索引
主要用來查找文本中的關鍵字,而不是直接與索引中的值相比較。
fulltext索引跟其它索引大不相同,它更像是一個搜索引擎,而不是簡單的where語句的參數匹配。
fulltext索引配合match against操作使用,而不是一般的where語句加like。
它可以在create table,alter table ,create index使用,不過目前只有char、varchar,text 列上可以創建全文索引。
- 聚集索引:聚簇索引的順序就是數據的物理存儲順序,索引與數據存放在同一個文件中。 (表中各行的物理順序與鍵值的邏輯(索引)順序相同,每個表只能有一個)
- 非聚集索引:非聚簇索引的順序與數據的物理存儲順序不同,索引與數據存放在不同的文件。 (非聚集索引指定表的邏輯順序。數據存儲在一個位置,索引存儲在另一個位置,索引中包含指向數據存儲位置的指針。可以有多個,小於249個)
(3)按應用層次分類:
(1)普通索引
最基本的索引,它沒有任何限制,用於加速查詢。
(2)唯一索引
索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。
(3)主鍵索引
是一種特殊的唯一索引,一個表只能有一個主鍵,不允許有空值。一般是在建表的時候同時創建主鍵索引。
(4)組合索引
指多個字段上創建的索引,只有在查詢條件中使用了創建索引時的第一個字段,索引才會被使用。使用組合索引時遵循最左前綴集合。
(5)全文索引
主要用來查找文本中的關鍵字,而不是直接與索引中的值相比較。
fulltext索引跟其它索引大不相同,它更像是一個搜索引擎,而不是簡單的where語句的參數匹配。
fulltext索引配合match against操作使用,而不是一般的where語句加like。
它可以在create table,alter table ,create index使用,不過目前只有char、varchar,text 列上可以創建全文索引。
6.主鍵與唯一索引的區別
主鍵是一種約束,唯一索引是一種索引,兩者在本質上是不同的。 主鍵創建后一定包含一個唯一性索引,唯一性索引並不一定就是主鍵。 唯一性索引列允許空值,而主鍵列不允許為空值。 主鍵列在創建時,已經默認為空值 + 唯一索引了。
主鍵可以被其他表引用為外鍵,而唯一索引不能。 一個表最多只能創建一個主鍵,但可以創建多個唯一索引。 主鍵更適合那些不容易更改的唯一標識,如自動遞增列、身份證號等。 在 RBO 模式下,主鍵的執行計划優先級要高於唯一索引。 兩者可以提高查詢的速度。
主鍵是一種約束,唯一索引是一種索引,兩者在本質上是不同的。 主鍵創建后一定包含一個唯一性索引,唯一性索引並不一定就是主鍵。 唯一性索引列允許空值,而主鍵列不允許為空值。 主鍵列在創建時,已經默認為空值 + 唯一索引了。
主鍵可以被其他表引用為外鍵,而唯一索引不能。 一個表最多只能創建一個主鍵,但可以創建多個唯一索引。 主鍵更適合那些不容易更改的唯一標識,如自動遞增列、身份證號等。 在 RBO 模式下,主鍵的執行計划優先級要高於唯一索引。 兩者可以提高查詢的速度。
7.什么情況下該創建索引?
頻繁作為查詢條件的字段應該創建索引;
查詢中與其他表有關聯的字段,例如外鍵關系;
在經常需要排序(order by),分組(group by)和的distinct 列上加索引,可以加快排序查詢的時間,
頻繁作為查詢條件的字段應該創建索引;
查詢中與其他表有關聯的字段,例如外鍵關系;
在經常需要排序(order by),分組(group by)和的distinct 列上加索引,可以加快排序查詢的時間,
8.什么情況下不創建索引?
(1)查詢中很少使用到的字段 不應該創建索引,如果建立了索引然而還會降低mysql的性能和增大了空間需求.
(2)值重復率高的字段不適合建索引(比如性別、百萬級數據時比如26個字母)
數據很少的字段也不應該建立索引,比如 一個性別字段 0或者1,在查詢中,結果集的數據占了表中數據行的比例比較大,mysql需要掃描的行數很多,增加索引,並不能提高效率
(3)定義為text和image和bit數據類型的列不應該增加索引,
(4)當表的修改(UPDATE,INSERT,DELETE)操作遠遠大於檢索(SELECT)操作時不應該創建索引,這兩個操作是互斥的關系
(1)查詢中很少使用到的字段 不應該創建索引,如果建立了索引然而還會降低mysql的性能和增大了空間需求.
(2)值重復率高的字段不適合建索引(比如性別、百萬級數據時比如26個字母)
數據很少的字段也不應該建立索引,比如 一個性別字段 0或者1,在查詢中,結果集的數據占了表中數據行的比例比較大,mysql需要掃描的行數很多,增加索引,並不能提高效率
(3)定義為text和image和bit數據類型的列不應該增加索引,
(4)當表的修改(UPDATE,INSERT,DELETE)操作遠遠大於檢索(SELECT)操作時不應該創建索引,這兩個操作是互斥的關系
9.為什么性別不適合創建索引?
因為你訪問索引需要付出額外的IO開銷,你從索引中拿到的只是地址,要想真正訪問到數據還是要對表進行一次IO。
假如你要從表的100萬行數據中取幾個數據,那么利用索引迅速定位,訪問索引的這IO開銷就非常值了。
但如果你是從100萬行數據中取50萬行數據,就比如性別字段,那你相對需要訪問50萬次索引,再訪問50萬次表,加起來的開銷並不會比直接對表進行一次完整掃描小。
因為你訪問索引需要付出額外的IO開銷,你從索引中拿到的只是地址,要想真正訪問到數據還是要對表進行一次IO。
假如你要從表的100萬行數據中取幾個數據,那么利用索引迅速定位,訪問索引的這IO開銷就非常值了。
但如果你是從100萬行數據中取50萬行數據,就比如性別字段,那你相對需要訪問50萬次索引,再訪問50萬次表,加起來的開銷並不會比直接對表進行一次完整掃描小。