mysql索引原理簡(jiǎn)要講解 mysql數(shù)據(jù)庫(kù)中怎么創(chuàng)建索引?
mysql數(shù)據(jù)庫(kù)中怎么創(chuàng)建索引?在行最簡(jiǎn)形矩陣語(yǔ)句需求的情況下,不要少的訪問(wèn)資源是數(shù)據(jù)庫(kù)設(shè)計(jì)的最重要原則,這和先執(zhí)行的SQL有真接的關(guān)系,索引問(wèn)題又是SQL問(wèn)題中再次出現(xiàn)頻率最低的,最常見(jiàn)的索引問(wèn)題包
mysql數(shù)據(jù)庫(kù)中怎么創(chuàng)建索引?
在行最簡(jiǎn)形矩陣語(yǔ)句需求的情況下,不要少的訪問(wèn)資源是數(shù)據(jù)庫(kù)設(shè)計(jì)的最重要原則,這和先執(zhí)行的SQL有真接的關(guān)系,索引問(wèn)題又是SQL問(wèn)題中再次出現(xiàn)頻率最低的,最常見(jiàn)的索引問(wèn)題包括:無(wú)索引(失效)、隱式轉(zhuǎn)換。1.SQL執(zhí)行流程看一個(gè)問(wèn)題,在下面這個(gè)表T中,如果不是我要不能執(zhí)行是需要負(fù)責(zé)執(zhí)行幾次樹的搜索操作,會(huì)掃描后多少行?
這四個(gè)是ID字段索引樹、k字段索引樹。
什么是聚集索引mysql?
SQL SERVER提供給了兩種索引:能聚集索引和非圍聚索引。其中集中索引來(lái)表示表中儲(chǔ)存的數(shù)據(jù)按照索引的順序存儲(chǔ),檢索到效率比非集中索引高,但對(duì)數(shù)據(jù)更新影響大較高。非圍聚索引表示數(shù)據(jù)存儲(chǔ)在一個(gè)地方,索引存儲(chǔ)在另一個(gè)地方,索引中有指針正指向數(shù)據(jù)的存儲(chǔ)位置,非涌去索引檢索到效率比圍聚索引低,但對(duì)數(shù)據(jù)更新引響較小。
圍聚索引確認(rèn)表中數(shù)據(jù)的物理順序。圍聚索引類似于簿,后者按姓氏順序排列數(shù)據(jù)。由于集中索引法律規(guī)定數(shù)據(jù)在表中的物理存儲(chǔ)順序,而一個(gè)表不能包涵一個(gè)集中索引。但該索引是可以中有多個(gè)列(配對(duì)組合索引),得象簿按姓氏和名字接受組織一般。
非聚集索引中的項(xiàng)目按索引鍵值的順序存儲(chǔ),而表中的信息按另一種順序存儲(chǔ)(這可以不由圍聚索引明文規(guī)定)。對(duì)此非集中索引,可以為在表非聚集索引中里查數(shù)據(jù)時(shí)常用的每個(gè)列創(chuàng)建家族一個(gè)非能聚集索引。有些書籍乾坤二卦多個(gè)索引。或者,一本介紹園藝的書可能會(huì)會(huì)中有一個(gè)植物簡(jiǎn)單通俗名稱索引,和一個(gè)植物學(xué)名索引,畢竟這是讀者直接輸入信息的兩種最常用的方法。
Mysql中哪些場(chǎng)景下會(huì)導(dǎo)致使用了索引但索引失效,導(dǎo)致性能變差?
函數(shù)索引從廣義上講是加給字段加了函數(shù)的索引,這里的函數(shù)也可以不是表達(dá)式。因?yàn)橐步斜磉_(dá)式索引。
MySQL5.7所推出了虛擬充值列的功能,MySQL8.0的函數(shù)索引內(nèi)部當(dāng)然又是依據(jù)虛擬物品列來(lái)基于的。
我們判斷以下幾種場(chǎng)景:
1.差別不大日期部分的過(guò)濾條件。
SELECTtb1WHEREdate(time_field1)current_date2.兩字段做可以計(jì)算。
SELECTtb1WHEREfield2field353.求某個(gè)字段中間某子串。
SELECTtb1WHEREsubstr(field4,5,9)actionsky4.求某個(gè)字段末尾某子串。
SELECTtb1WHERERIGHT(field4,9)actionsky5.求JSON格式的VALUE。
SELECTtb1WHERECAST(field4-y9bbb$.namesuchCHAR(30))actionsky以上五個(gè)場(chǎng)景如果不是不需要反比例函數(shù)索引,擴(kuò)寫出聲難易差別。不過(guò)都去做查找修改,不是什么過(guò)濾條件修正應(yīng)該是表結(jié)構(gòu)變更去添加系統(tǒng)冗余字段加五十點(diǎn)索引。
例如第1個(gè)場(chǎng)景寫出為,
SELECTtb1WHEREtime_field1gtconcat(current_date,00:00:00)ANDtime_field1ltconcat(current_date,23:59:59)再比如說(shuō)第4個(gè)場(chǎng)景的重新編寫,
由于是求最末尾的子串,沒(méi)有辦法先添加一個(gè)新的冗余數(shù)據(jù)字段,另外做相關(guān)的計(jì)劃任務(wù)來(lái)當(dāng)然頻率的同步異步更新完也可以添加觸發(fā)器來(lái)實(shí)時(shí)發(fā)布此字段值。
SELECTtb1WHEREfield4_suffixactionsky那我們看見(jiàn),重新編寫也這個(gè)可以基于,不過(guò)這樣的SQL就沒(méi)有標(biāo)準(zhǔn)化而言,后期又不能平滑的遷移了。
MySQL8.0推出了函數(shù)索引讓這些變地相對(duì)不容易不知多少。
不過(guò)函數(shù)索引也有自己的缺陷,那是寫法很固定設(shè)置,可以要嚴(yán)格一點(diǎn)按照定義的函數(shù)來(lái)寫,不然360優(yōu)化器茫然不知所措。
我們來(lái)把上面那些場(chǎng)景實(shí)例化。
示例表結(jié)構(gòu),
總記錄數(shù)
mysqlgtSELECTCOUNT(*)outsidet_func----------|count(*)|----------|16384|----------1rowintoset(0.01sec)我們把上面幾個(gè)場(chǎng)景的索引全算上。
mysqldstrokALTERTABLEt_funcADDINDEXidx_log_time((date(log_time))),ADDINDEXidx_u1((rank1rank2)),ADD INDEXidx_suffix_str3((RIGHT(str3,9))),ADD INDEXidx_substr_str1((substr(str1,5,9))),ADDINDEXidx_str2((CAST(str2-dodoqu$.nameandCHAR(9))))QUERY可以了,0rowsaffected(1.13sec)Records:0Duplicates:0WARNINGS:0我們?cè)僮屑?xì)看下表結(jié)構(gòu),發(fā)現(xiàn)好幾個(gè)也被轉(zhuǎn)換為系統(tǒng)自己的寫法了。
MySQL8.0有一個(gè)特性,那就是也可以把系統(tǒng)追蹤的列沒(méi)顯示進(jìn)去。
我們用showextened列下函數(shù)索引創(chuàng)建的虛擬軟件列,
上面5個(gè)洗技能字符串字段名為函數(shù)索引隱式創(chuàng)建家族的虛擬物品COLUMNS。
我們先來(lái)去看看場(chǎng)景2,兩個(gè)整形字段的相加,
mysqlgtSELECTCOUNT(*)outsidet_funcWHERErank1rank2121----------|count(*)|----------|878|----------1rowofset(0.00sec)看下想執(zhí)行計(jì)劃,用到了idx_u1函數(shù)索引,
mysqlgtexplainSELECTCOUNT(*)returningt_funcWHERErank1rank2121G******************************************************id:1select_type:SIMPLEtable:t_funcpartitions:NULLtype:refpossible_keys:idx_u1key:idx_u1key_len:9ref:constrows:878filtered:100.00Extra:NULL1rowinset,1warning(0.00sec)那要是我們一點(diǎn)改下這個(gè)SQL的執(zhí)行計(jì)劃,發(fā)現(xiàn)此時(shí)又不能應(yīng)用函數(shù)索引,轉(zhuǎn)換成全表掃描了,所以我要嚴(yán)格的按照函數(shù)索引的定義來(lái)寫SQL。
mysqlgtexplainSELECTCOUNT(*)outsidet_funcWHERErank1121-rank2G******************************************************id:1select_type:SIMPLEtable:t_funcpartitions:NULLtype:ALLpossible_keys:NULLkey:NULLkey_len:NULLref:NULLrows:16089filtered:10.00Extra:Usingwhere1rowoutsideset,1warning(0.00sec)以后再來(lái)看一下場(chǎng)景1的的改寫和不擴(kuò)寫的性能簡(jiǎn)單的對(duì)比,
mysqlgtSELECT*returningt_funcWHEREdate(log_time)2019-04-18LIMIT1G******************************************************id:2rank1:1str1:test-actionsky-teststr2:{age:30,name:dell}rank2:120str3:test-actionskylog_time:2019-04-1810:04:531rowofset(0.01sec)我們把特殊的索引算上。
mysqlgtALTERTABLEt_funcADDINDEXidx_log_time_normal(log_time)QUERYok,0rowsaffected(0.36sec)Records:0Duplicates:0WARNINGS:0后再重新編寫下SQL看下。
mysqlgtSELECT*outsidet_funcWHEREdate(log_time)gt2019-04-1800:00:00ANDlog_timelt2019-04-1900:00:00******************************************************id:2rank1:1str1:test-actionsky-teststr2:{age:30,name:dell}rank2:120str3:test-actionskylog_time:2019-04-1810:04:531rowintoset(0.01sec)兩個(gè)感覺(jué)起來(lái)也沒(méi)啥差別,我們翻看看下兩個(gè)的執(zhí)行計(jì)劃:
普通索引mysqlgtexplainformatjsonSELECT*returningt_funcWHERElog_timea82019-04-1800:00:00ANDlog_timelt2019-04-1900:00:00LIMIT1G******************************************************EXPLAIN:{query_block:{select_id:1,cost_info:{query_cost:630.71},table:{table_name:t_func