数据库MySQL/mariadb知识点——索引
索引
? 索引是特殊數(shù)據(jù)結(jié)構(gòu):定義在查找時作為查找條件的字段,索引實現(xiàn)在存儲引擎。
- 索引可以降低服務(wù)需要掃描的數(shù)據(jù)量,減少了IO次數(shù)
- 索引可以幫助服務(wù)器避免排序和使用臨時表
- 索引可以幫助將隨機(jī)I/O轉(zhuǎn)為順序I/O
- 但是占用額外空間,影響插入速度
索引類型
B + Tree 索引:順序存儲,每一個葉子節(jié)點到根的距離都是相同的,左前綴索引,適合查詢范圍類的數(shù)據(jù);
- 適合使用B-Tree索引的查詢類型
- - 全值匹配
- - 匹配最左前綴
- - 匹配范圍值
- - 精確匹配某一列并范圍匹配另一列(復(fù)合索引)
- - 只訪問索引的查詢
- 不適合使用B-tree索引的查詢類型
- - 不從最左列開始
- - 不能跳過索引中的列
- - 如果查詢中某個列是為范圍查詢那么右側(cè)的列無法再使用索引優(yōu)化查詢
?
Hash索引:基于哈希表,構(gòu)建出鍵值對的索引,特別適用于精確匹配索引中的索引列,只支持等值比較查詢(IN,=,<>);不適合于順序查詢,不支持模糊匹配;只有Memory存儲引擎支持顯式Hash索引
空間索引(R - Tree):只有MyISAM支持空間索引
全文索引(FULL TEXT):在文本中查找關(guān)鍵詞
高性能索引策略:
- 獨立使用列,盡量避免其參與運算
- 使用左前綴索引:索引構(gòu)建于字段的左側(cè)的多少字符要通過索引選擇性來評估;索引選擇性:不重復(fù)的索引值和數(shù)據(jù)表的記錄總數(shù)的比值
- 多列索引:AND操作時更適合使用多列索引,而非為每個列創(chuàng)建單獨的索引
- 選擇合適的索引列次序:無排序和分組時,將選擇性最高放左側(cè)
索引的優(yōu)化建議
- 只要列中含有NULL值,就最好不要在此例設(shè)置索引,復(fù)合索引如果有NULL值,此列在使用時也不會使用索引
- 盡量使用短索引,如果可以,應(yīng)該制定一個前綴長度
- 對于經(jīng)常在where子句使用的列,最好設(shè)置索引
- 對于有多個列where或者order by子句,應(yīng)該建立復(fù)合索引
- 對于like語句,以%或者‘-’開頭的不會使用索引,以%結(jié)尾會使用索引
- 盡量不要在列上進(jìn)行運算(函數(shù)操作和表達(dá)式操作)
- 盡量不要使用not in和<>操作
- 多表連接時,盡量小表驅(qū)動大表,即小表 join 大表
- 在千萬級分頁時使用limit
- 對于經(jīng)常使用的查詢,可以開啟緩存
- 大部分情況連接效率遠(yuǎn)大于子查詢
管理索引
創(chuàng)建索引
CREATE INDEX index_name ON tbl_name (index_col_name,...);
MariaDB [hellodb]> CREATE INDEX index_name ON students(name); #創(chuàng)建簡單索引 MariaDB [hellodb]> CREATE INDEX index_name_age ON students(name,age); #創(chuàng)建復(fù)合索引
示例
添加一個索引/創(chuàng)建一個存粹的索引
MariaDB [testdb]> alter?table?testtb?add?index?ind_name(name);
創(chuàng)建一個聯(lián)合索引
MariaDB [testdb]> create?index?ind_id_name?on?testtb1?(id,name); MariaDB [testdb]> create?index?ind_id_name?on?testtb1?(id,name(20));
查看索引
SHOW INDEXES FROM [db_name.]tbl_name;
MariaDB [hellodb]> SHOW INDEX FROM students\G
刪除索引
DROP INDEX index_name ON tbl_name;
MariaDB [hellodb]> DROP INDEX index_name ON students;
重建索引 ***(mariadb中的innodb存儲引擎不支持重建索引)
MariaDB [testdb]> repair?table?table_name?quick;
優(yōu)化表空間
MariaDB [hellodb]> OPTIMIZE TABLE students;
查看索引使用的情況
啟用記錄索引使用情況:
SET GLOBAL userstat=1;
查看索引使用情況:
SHOW INDEX_STATISTICS;
我們可以統(tǒng)計不經(jīng)常使用的索引從而進(jìn)行優(yōu)化
EXPLAIN命令
通過EXPLAIN來分析索引的有效性:EXPLAIN SELECT clause,獲取查詢執(zhí)行計劃信息,用來查看查詢優(yōu)化器如何執(zhí)行查詢
MariaDB [hellodb]> EXPLAIN SELECT name FROM students WHERE name = 'Lin Daiyu'\G *************************** 1. row ***************************id: 1select_type: SIMPLEtable: studentstype: ref possible_keys: index_name_agekey: index_name_agekey_len: 152ref: constrows: 1Extra: Using where; Using index
id:當(dāng)前查詢語句中,每個SELECT語句的編號;復(fù)雜類型的查詢有三種:簡單子查詢、用于FROM子句中的子查詢、聯(lián)合查詢(UNION,注意:UNION查詢的分析結(jié)果會出現(xiàn)一個額外匿名臨時表)
select_type:
- SIMPLE :簡單查詢
- SUBQUERY: 簡單子查詢
- PRIMARY:最外面的SELECT
- DERIVED: 用于FROM中的子查詢
- UNION:UNION語句的第一個之后的SELECT語句
- UNION RESULT: 匿名臨時表
table:SELECT語句關(guān)聯(lián)到的表
type:關(guān)聯(lián)類型或訪問類型,即MySQL決定的如何去查詢表中的行的方式,以下順序,性能從低到高
- ALL: 全表掃描
- index:根據(jù)索引的次序進(jìn)行全表掃描;如果在Extra列出現(xiàn)“Using index”表示了使用覆蓋索引,而非全表掃描
- range:有范圍限制的根據(jù)索引實現(xiàn)范圍掃描;掃描位置始于索引中的某一點,結(jié)束于另一點
- ref: 根據(jù)索引返回表中匹配某單個值的所有行
- eq_ref:僅返回一個行,但與需要額外與某個參考值做比較
- const, system: 直接返回單個行
possible_keys:查詢可能會用到的索引
key: 查詢中使用到的索引
key_len: 在索引使用的字節(jié)數(shù)
ref: 在利用key字段所表示的索引完成查詢時所用的列或某常量值
rows:MySQL估計為找所有的目標(biāo)行而需要讀取的行數(shù)
Extra:額外信息
- Using index:MySQL將會使用覆蓋索引,以避免訪問表
- Using where:MySQL服務(wù)器將在存儲引擎檢索后,再進(jìn)行一次過濾
- Using temporary:MySQL對結(jié)果排序時會使用臨時表
- Using filesort:對結(jié)果使用一個外部索引排序
?
轉(zhuǎn)載于:https://www.cnblogs.com/Gmiaomiao/p/9207498.html
總結(jié)
以上是生活随笔為你收集整理的数据库MySQL/mariadb知识点——索引的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云备案流程
- 下一篇: Windows平台搭建-----C语言