nubby mysql_Mysql索引 - osc_nubn2pd9的个人空间 - OSCHINA - 中文开源技术交流社区
索引優(yōu)先級
索引原理:
通過不斷的縮小想要獲得數據的范圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是我們總是通過同一種查找方式來鎖定數據。
B_TREE索引:
mysql 中的索引:
1)B_TREE索引:
最常見的索引,大部分引擎都支持。
2)HASH索引:
相對簡單,只有memory和heap引擎支持hash索引。
hash索引適用于key-VALUES 查詢,通過hash索引要比BTREE索引查詢更迅速;
hash索引不支持范圍查詢,例如 ,>= <= 這類操作。并且只有 在 = 的條件下才會使用where索引。
只有memory 引擎支持,使用場景簡單。
3)R_TREE索引(空間索引)
空間索引是MyISAM的一個特殊索引類型,主要用于地理空間數據類型,通常使用較少。
4)Full_Text索引(全文索引)
也是MyISAM的一個特殊索引類型,InnoDB從5.6開始支持Full Text 索引。
1、索引優(yōu)點:
加快查詢速度
2、索引缺點:
降低數據插入、刪除和更新的速度,占用磁盤空間
3、創(chuàng)建索引原則:
1)為用于搜索、排序或分組的列創(chuàng)建索引,而對于輸出顯示的列不創(chuàng)建索引;
即:最佳索引列是在where子句中的列,連接子句中的列,或出現在group by、order by子句中的列。
2)列的基數越高,索引的效果越好;
列的基數:列中所有非重復值的個數。
3)索引短小值:盡量使用較小的數據類型(能用25個字符的,就不要用100字符);
短小值可以讓比較操作更快,從而加快索引查找的速度;
短小值可以讓索引短小,從而減少對磁盤I/O的請求;
對于更短小的鍵值,鍵緩存里的索引塊可以容納更多的鍵值。如果Mysql能在內存里同時容納更多的鍵,那么就可以在不去磁盤讀取更多索引塊的情況下,提高找到鍵值的幾率。
4)索引字符串值的前綴:對字符串進行索引,盡可能指定前綴的長度;
快且省空間。
5)利用最左前綴
當創(chuàng)建N個列的復合索引時,Mysql實際上是創(chuàng)建N個索引。復合索引相當于多索引,所以第一個索引列的值比較關鍵。
如復合索引(C1、C2、C3)可用于搜索:C1、C2、C3和C1、C2或C1,卻不能搜索C2、C3
6)不要建立過多的索引;
7)讓參與比較的索引類型保持匹配
InnoDB:B樹索引
MyISAM:B樹索引和R數索引(空間類型)
MEMORY:默認散列索引,也支持B數索引
散列索引:在使用運算符=或<=>完成精確匹配的比較操作,速度非常快;但用于查找某個范圍值的比較,速度欠佳。
B數索引:在使用=、>、<>、!=和between運算符,進行精確比較或范圍比較時,效率高;如果匹配純字符串,而不是通配符作為開頭的,還可以用LIKE進行匹配。
8)利用慢查詢日志找出那些性能低的查詢;
慢查詢日志:是一個文本文件。如果某個給定的查詢在這個日志里頻繁出現,那么這個查詢可能就不是最優(yōu)的,需要改寫。
通過慢查詢日志定位那些執(zhí)行效率較低的 SQL 語句,用--log-slow-queries[=file_name]選項啟動時,mysqld 寫一個包含所有執(zhí)行時間超過 long_query_time 秒的 SQL 語句的日志文件。
慢查詢日志在查詢結束以后才紀錄,所以在應用反映執(zhí)行效率出現問題的時候查詢慢查詢日志并不能定位問題,可以使用 show processlist 命令查看當前 MySQL 在進行的線程,包括線程的狀態(tài)、是否鎖表等,可以實時地查看 SQL 的執(zhí)行情況,同時對一些鎖表操作進行優(yōu)化。
4、優(yōu)化程序對索引的利用
1)*分析表
analyze table 表名;使服務器生成關于鍵值分布情況的統計數據。
2)*使用EXPLAIN驗證優(yōu)化程序的操作
explain顯示了mysql如何使用索引來處理select語句以及連接表。可以幫助選擇更好的索引和寫出更優(yōu)化的查詢語句。
3)通過show profile 分析sql
通過 having_profiling參數,能夠查詢是否支持profile
為1即為開啟。
>select count(*) from? payment:
>show profiles; //可以查詢到該sql 的query ID為4;假設為4
>show profile for query 4; //能夠查詢到執(zhí)行過程中線程的每個狀態(tài)和消耗的時間;
4)/通過trace 分析優(yōu)化器如何選擇執(zhí)行計劃
5.6后提供了對sql的跟蹤trace,通過trace文件能夠進一步了解為什么優(yōu)化器選擇了A執(zhí)行計劃而不選擇B執(zhí)行計劃。
使用方式:
首先打開track,設置格式為JSON,設置track最大能有使用內存的大小,避免解析過程中因為內存過小而不能完整顯示。
>set optimizer_trace="enable=on",END_MARKERS_IN_JSON=ON;
>set optimizer_trace_max_mem_size = 1000000;
接下來執(zhí)行想做trace的SQL語句。
select * from? .....;
最后 檢查 INFORMATION_SCHEMA.OPTIMIZER_TRACE 就可以知道m(xù)ysql 是如何執(zhí)行sql 的
>SELECT * FROM INFORMATION.OPTIMIZER_TRACE \G;//會輸出一個json格式的跟蹤文件。
5)必要時給予優(yōu)化程序提示或改寫它
可以在表名的后面加上FORCE INDEX、USE INDEX或IGNORE INDEX。
也可以用帶有STRAIGHT_JOIN,來強制各個表按照它們在from子句里的排列順序來連接表。所以可以把能查詢出行數最小的表放在最前面。
6)比較擁有相同數據類型的列
7)讓索引列在比較表達式中單獨出現
當索引列在復雜的算術表達式或函數中,不會使用索引。
8)不要在like模式的開始位置使用通配符
不能%String%,應該string%
9)測試查詢的各種替代形式,并多次運行它們
10)避免過多使用自動類型轉換
如把一個字符串類型與一個數值類型比較,就不會用到索引。
6、選擇利于高效查詢的數據類型
1)多用數字運算,少用字符串運算
2)當較小類型夠用時,就不用較大類型
3)把數據列聲明成 not null
因為查詢時,不用判斷值是否為null
4)考慮使用ENUM列
如果字符串列的基數低(即差異值的個數很少),則可以考慮轉換成ENUM列。ENUM列的內部表示形式為數字。
5)*使用procedure analyse()
PROCEDURE ANALYSE() 會讓 MySQL 幫你去分析你的字段和其實際的數據,并會給你一些有用的建議。只有表中有實際的數據,這些建議才會變得有用,因為要做一些大的決定是需要有數據作為基礎的。
得到分析結果:
字段最小值,最大值,最小長度,最大長度,還有最后Optimal_fieldtype代表了表結構建議,可以根據數據分析建議來修改表結構,使之更符合數據存儲規(guī)范。
6)整理表碎片
碎片占空間,影響讀取的性能。
7)把數據壓縮到BLOB或TEXT列
8)使用合成索引
做法:先根據表里的其他列算出一個散列值,把它存到一個單獨的列里。然后通過檢索散列值進行查詢(缺點是只能用于精確匹配型查詢)。數字型的散列值的存儲效率非常高。
9)避免檢索很大的BLOB或TEXT值
10)把BLOB或TEXT列剝離出來,形成一個單獨的表
前提:這樣做可以讓你把這個表的其他列轉換成行固定長度的格式。這樣可以減少主表的碎片。
7、*使用SQL提示(SQL HINT)
在SQL語句中加入一些人為的提示來達到優(yōu)化操作的目的。
1)USE INDEX
來提示希望mysql去參考的索引列表,就可以讓mysql不再考慮其他可用的索引。
2)IGNORE INDEX
讓MySQL忽略一個或多個索引
3)FORCE INDEX
強制mysql使用一個特定的索引
8、*組合索引的生效原則是
從前往后依次使用生效,如果中間某個索引沒有使用,那么斷點前面的索引部分起作用,斷點后面的索引沒有起作用;
比如
where?a=3?and?b=45?and?c=5?.... 這種三個索引順序使用中間沒有斷點,全部發(fā)揮作用;
where?a=3?and?c=5... 這種情況下b就是斷點,a發(fā)揮了效果,c沒有效果;
where?b=3?and?c=4... 這種情況下a就是斷點,在a后面的索引都沒有發(fā)揮作用,這種寫法聯合索引沒有發(fā)揮任何效果;
where?b=45?and?a=3?and?c=5?.... 這個跟第一個一樣,全部發(fā)揮作用,abc只要用上了就行,跟寫的順序無關
9、*mysql索引合并:一條sql可以使用多個索引
1)索引合并是把幾個索引的范圍掃描合并成一個索引。
2)索引合并的時候,會對索引進行并集,交集或者先交集再并集操作,以便合并成一個索引。
3)這些需要合并的索引只能是一個表的。不能對多表進行索引合并。
怎么確定使用了索引合并
在使用explain對sql語句進行操作時,如果使用了索引合并,那么在輸出內容的type列會顯示 index_merge,key列會顯示出所有使用的索引。例如:
建表語句:
SQL 1:
SQL 2:
相同模式的sql語句,可能有時能使用索引,有時不能使用索引。是否能使用索引,取決于mysql查詢優(yōu)化器對統計數據分析后,是否認為使用索引更快。因此,單純的討論一條sql是否可以使用索引有點片面,還需要考慮數據。
10、*Mysql的group by的select條件可以不是分組字段或聚合函數。
MySQL擴展了GROUP?BY的用途,因此你可以使用SELECT列表中不出現在GROUP?BY語句中的列或運算。這代表“對該組的任何可能值”。你會得到非預測性結果。
? ? ? ? ? ? ? ? ? ? ??
問題:
建表語句:
/mysql?索引優(yōu)先級規(guī)則是如何的?
例如:
索引1:名字為idx_lastTime_deviceType_version,
索引字段(`last_access_time`,`device_type`,`version`)
索引2:名字為idx_lastTime_deviceType_provinceId,
索引字段(`last_access_time`,`device_type`,`province_id`)
在執(zhí)行一條查詢語句,用到last_access_time,device_type這2個索引。mysql如何去選擇1或者2呢
1)where、group by、order by、join語句上的優(yōu)化。
2)在WHERE語句上的優(yōu)化相同,然后MYSQS會根據你的select?...中的輸出列來斷定用哪一個索引,或者和其它表JOIN時哪個索引更有利。
3)索引的創(chuàng)建順序也影響索引優(yōu)先級。
先建立idx_lastTime_deviceType_provinceId:
先建立idx_lastTime_deviceType_version:
查詢sql 1:
這個SQL用的索引是idx_lastTime_deviceType_version(last_access_time, device_type, version)
查詢sql 2:
這個SQL用的索引是idx_lastTime_deviceType_version(last_access_time, device_type, version)
查詢sql 3:
這個SQL用的索引是idx_lastTime_deviceType_provinceId(last_access_time, device_type, province_Id)
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的nubby mysql_Mysql索引 - osc_nubn2pd9的个人空间 - OSCHINA - 中文开源技术交流社区的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kfaka storm写入mysql_f
- 下一篇: linux cmake编译源码,linu