真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

mysql多字段怎么優(yōu)化,mysql數(shù)據(jù)庫優(yōu)化的幾種方式

mysql 一張有近一百個字段的表,通過主鍵查詢數(shù)據(jù)非常慢,查詢一條數(shù)據(jù)需要2秒左右。怎么作優(yōu)化

1張表100個字段。。。。分表,然后用表外連接查詢可以調(diào)高查詢效率,也可以用復(fù)合查詢,不過復(fù)合查詢效率沒有外連接查詢效率高,但是sql語句寫起來方便。如果數(shù)據(jù)量不是上百萬級別的,推薦用復(fù)合查詢。

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括肅寧網(wǎng)站建設(shè)、肅寧網(wǎng)站制作、肅寧網(wǎng)頁制作以及肅寧網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,肅寧網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到肅寧省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

mysql---索引優(yōu)化

索引就是為特定的mysql字段進(jìn)行一些特定的算法排序,比如二叉樹的算法和哈希算法,哈希算法是通過建立特征值,然后根據(jù)特征值來快速查找。

1.普通索引:(index)最基本的索引,沒有任何限制? 目的:加快數(shù)據(jù)的查詢速度

2.唯一索引:(unique)? 與"普通索引"類似,不同的就是:索引列的值必須唯一,但允許有空值。

3.主鍵索引(primary key) 它 是一種特殊的唯一索引,不允許有空值。

4.復(fù)合索引:index(a,b,c)? 為了更多的提高mysql效率可建立組合索引,遵循”最左前綴“原則。

5.全文索引:fulltext? 僅可用于 MyISAM 表,針對較大的數(shù)據(jù),生成全文索引很耗時耗空間。

第一類是myisam存儲引擎使用的叫做b-tree結(jié)構(gòu),

第二類是innodb存儲引擎使用的叫做聚簇結(jié)構(gòu)(也是一種 b-tree)。 如下圖:

注意:

1.myisam不需要回行處理?

2.innodb不需要回行處理,直接可以獲取數(shù)據(jù),因?yàn)閕nnodb的儲存引擎是包含了數(shù)據(jù)和索引文件的,其主鍵索引包含了數(shù)據(jù),(唯一索引及普通索是沒有直接包含數(shù)據(jù)的)

1、索引列不能參與計(jì)算

有索引列參與計(jì)算的查詢條件對索引不友好(甚至無法使用索引),如from_unixtime(create_time) = '2014-05-29'。

原因很簡單,如何在節(jié)點(diǎn)中查找到對應(yīng)key?如果線性掃描,則每次都需要重新計(jì)算,成本太高;如果二分查找,則需要針對from_unixtime方法確定大小關(guān)系。

因此,索引列不能參與計(jì)算。上述from_unixtime(create_time) = '2014-05-29'語句應(yīng)該寫成create_time = unix_timestamp('2014-05-29')。

2、最左前綴匹配

如有索引(a, b, c, d),查詢條件a = 1 and b = 2 and c 3 and d = 4,則會在每個節(jié)點(diǎn)依次命中a、b、c,無法命中d。也就是最左前綴匹配原則。

3、冗余和重復(fù)索引

冗余索引是指在相同的列上按照相同的順序創(chuàng)建的相同類型的索引,應(yīng)當(dāng)盡量避免這種索引,發(fā)現(xiàn)后立即刪除。比如有一個索引(A,B),再創(chuàng)建索引(A)就是冗余索引。冗余索引經(jīng)常發(fā)生在為表添加新索引時,比如有人新建了索引(A,B),但這個索引不是擴(kuò)展已有的索引(A)

4、避免多個范圍條件

? ? select user.* from user where login_time '2017-04-01' and age between 18 and 30;

比如想查詢某個時間段內(nèi)登錄過的用戶:它有兩個范圍條件,login_time列和age列,MySQL可以使用login_time列的索引或者age列的索引,但無法同時使用它們 .

5、覆蓋索引 (能擴(kuò)展就不新建)

如果一個索引包含或者說覆蓋所有需要查詢的字段的值,那么就沒有必要再回表查詢,這就稱為覆蓋索引。覆蓋索引是非常有用的工具,可以極大的提高性能,因?yàn)椴樵冎恍枰獟呙杷饕龝碓S多好處:

1.索引條目遠(yuǎn)小于數(shù)據(jù)行大小,如果只讀取索引,極大減少數(shù)據(jù)訪問量2.索引是有按照列值順序存儲的,對于I/O密集型的范圍查詢要比隨機(jī)從磁盤讀取每一行數(shù)據(jù)的IO要少的多

6、選擇區(qū)分度高的列作索引

如,用性別作索引,那么索引僅能將1000w行數(shù)據(jù)劃分為兩部分(如500w男,500w女),索引幾乎無效。

區(qū)分度的公式是count(distinct ) / count(*),表示字段不重復(fù)的比例,比例越大區(qū)分度越好。唯一鍵的區(qū)分度是1,而一些狀態(tài)、性別字段可能在大數(shù)據(jù)面前的區(qū)分度趨近于0。

7、刪除長期未使用的索引

場景一(覆蓋索引 5)

索引應(yīng)該建在選擇性高的字段上(鍵值唯一的記錄數(shù)/總記錄條數(shù)),選擇性越高索引的效果越好、價值越大,唯一索引的選擇性最高;

組合索引中字段的順序,選擇性越高的字段排在最前面;

where條件中包含兩個選擇性高的字段時,可以考慮分別創(chuàng)建索引,引擎會同時使用兩個索引(在OR條件下,應(yīng)該說必須分開建索引);

不要重復(fù)創(chuàng)建彼此有包含關(guān)系的索引,如index1(a,b,c) 、index2(a,b)、index3(a);

組合索引的字段不要過多,如果超過4個字段,一般需要考慮拆分成多個單列索引或更為簡單的組合索引;

不要濫用索引。因?yàn)檫^多的索引不僅僅會增加物理存儲的開銷,對于插入、刪除、更新操作也會增加處理上的開銷,而且會增加優(yōu)化器在選擇索引時的計(jì)算代價。

因此太多的索引與不充分、不正確的索引對性能都是毫無益處的。一言以蔽之,索引的建立必須慎重,對每個索引的必要性都應(yīng)該經(jīng)過仔細(xì)分析,要有建立的依據(jù)。

MySql中LongText類型大字段查詢優(yōu)化

1.mysql在操作數(shù)據(jù)的時候,以page為單位

??不管是更新,插入,刪除一行數(shù)據(jù),都需要將那行數(shù)據(jù)所在的page讀到內(nèi)存中,然后在進(jìn)行操作,這樣就存在一個命中率的問題,如果一個page中能夠相對的存放足夠多的行,那么命中率就會相對高一些,性能就會有提升

2.innodb的page大小默認(rèn)為16kb

??innodb存儲引擎表為索引組織表,樹底層的葉子節(jié)點(diǎn)為一雙向鏈表,因此每個頁中至少應(yīng)該有兩行記錄,這就決定了innodb在存儲一行數(shù)據(jù)的時候不能夠超過8k,但事實(shí)上應(yīng)該更小,有一些InnoDB內(nèi)部數(shù)據(jù)結(jié)構(gòu)要存儲以及預(yù)留操作空間,

3.blob,text大字段

??innodb只會存放前768字節(jié)在數(shù)據(jù)頁中,而剩余的數(shù)據(jù)則會存儲在溢出段中(發(fā)生溢出情況的時候適用),最大768字節(jié)的作用是便于創(chuàng)建前綴索引/prefix index,其余更多的內(nèi)容存儲在額外的page里,哪怕只是多了一個字節(jié)。因此,所有列長度越短越好

4.擴(kuò)展存儲禁用了自適應(yīng)哈希

??因?yàn)樾枰暾谋容^列的整個長度,才能發(fā)現(xiàn)是不是正確的數(shù)據(jù)(哈希幫助InnoDB非??焖俚恼业健安聹y的位置”,但是必須檢查“猜測的位置”是不是正確)。因?yàn)樽赃m應(yīng)哈希是完全的內(nèi)存結(jié)構(gòu),并且直接指向Buffer Pool中訪問“最”頻繁的頁面,但對于擴(kuò)展存儲空間卻無法使用Adaptive Hash

變長大字段類型包括blob,text,varchar,其中varchar列值長度大于某數(shù)N時也會存溢出頁,在latin1字符集下N值可以這樣計(jì)算:innodb的塊大小默認(rèn)為16kb,由于innodb存儲引擎表為索引組織表,樹底層的葉子節(jié)點(diǎn)為一雙向鏈表,因此每個頁中至少應(yīng)該有兩行記錄,這就決定了innodb在存儲一行數(shù)據(jù)的時候不能夠超過8k,減去其它列值所占字節(jié)數(shù),約等于N。對于InnoDB,內(nèi)存是極為珍貴的,如果把768字節(jié)長度的blob都放在數(shù)據(jù)頁,雖然可以節(jié)省部分IO,但是能緩存行數(shù)就變少,也就是能緩存的索引值變少了,降低了索引效率

Mysql把每個BLOB和TEXT值當(dāng)作一個獨(dú)立的對象處理。存儲引擎在存儲時通常會做特殊處理。當(dāng)BLOB和TEXT值太大時,InnoDB會使用專門的“外部”儲存區(qū)域來進(jìn)行存儲,此時每個值在行內(nèi)需要1~4個字節(jié)存儲一個指針,然后在內(nèi)部存儲區(qū)域存儲實(shí)際的值。

Mysql不能將BLOB和TEXT列全部長度的字符串進(jìn)行索引

mysql的 io 以page為單位,因此不必要的數(shù)據(jù)(大字段)也會隨著需要操作的數(shù)據(jù)一同被讀取到內(nèi)存中來,這樣帶來的問題由于大字段會占用較大的內(nèi)存(相比其他小字段),使得內(nèi)存利用率較差,造成更多的隨機(jī)讀取。從上面的分析來看,我們已經(jīng)看到性能的瓶頸在于由于大字段存放在數(shù)據(jù)頁中,造成了內(nèi)存利用較差,帶來過多的隨機(jī)讀,那怎么來優(yōu)化掉這個大字段的影響

5.6版本以后,新增選項(xiàng) innodb_page_size 可以修改innodb的page默認(rèn)大小,但并不推薦修改這個配置

5.6版本之后mysql新增索引FULLTEXT可用來增加大文本搜索速度

MySQL性能優(yōu)化之索引設(shè)計(jì)

上一篇給小伙伴們講了關(guān)于SQL查詢性能優(yōu)化的相關(guān)技巧,一個好的查詢SQL離不開合理的索引設(shè)計(jì)。這篇小二就來嘮一嘮怎么合理的設(shè)計(jì)一個索引來優(yōu)化我們的查詢速度,要是有不合理的地方...嗯..

當(dāng)然啦,開個玩笑,歡迎小伙伴們指正!

通常情況下,字段類型的選擇是需要根據(jù)業(yè)務(wù)來判斷的,通常需要遵循以下幾點(diǎn)。

下列各種類型表格內(nèi)容來自菜鳥教程,權(quán)當(dāng)備忘。

優(yōu)化建議:

注意: INT(2)設(shè)置的為顯示寬度,而不是整數(shù)的長度,需要配合 ZEROFILL 使用 。

例如 id 設(shè)置為 TINYINT(2) UNSIGNED ,表示無符號,可以存儲的最大數(shù)值為255,其中 TINYINT(2) 沒有配合 ZEROFILL 實(shí)際沒有任何意義,例如插入數(shù)字200,長度雖然超過了兩位,但是這個時候是可以插入成功的,查詢結(jié)果同樣為200;插入數(shù)字5時,同樣查詢結(jié)果為5。

而 TINYINT(2) 配合 ZEROFILL 后,當(dāng)插入數(shù)字5時,實(shí)際存儲的還是5,不過在查詢是MySQL會在前面補(bǔ)上一個0,即查詢出來的實(shí)際為 05 。

優(yōu)化建議:

優(yōu)化建議:

通常來說,考慮好表中每個字段應(yīng)該使用什么類型和長度,建完表需要做的事情不是馬上建立索引,而是先把相關(guān)主體業(yè)務(wù)開發(fā)完畢,然后把涉及該表的SQL都拿出來分析之后再建立索引。

盡量少建立單值索引( 唯一索引除外 ),應(yīng)當(dāng)設(shè)計(jì)一個或者兩三個聯(lián)合索引,讓每一個聯(lián)合索引都盡量去包含SQL語句中的 where、order by、group by 的字段,同時確保聯(lián)合索引的字段順序盡量滿足SQL查詢的最左前綴原則。

索引基數(shù)是指這個字段在表里總共有多少個不同的值,比如一張表總共100萬行記錄,其中有個性別字段,性別一共有三個值:男、女、保密,那么該字段的基數(shù)就是3。

如果對這種小基數(shù)字段建立索引的話,因?yàn)樗饕龢渲兄挥心?、女、保密三個值,根本沒法進(jìn)行快速的二分查找,同時還需要回表查詢,還不如全表掃描嘞。

一般建立索引,盡量使用那些基數(shù)比較大的字段,那么才能發(fā)揮出B+樹快速二分查找的優(yōu)勢來。

在 where 和 order by 出現(xiàn)索引設(shè)計(jì)沖突時,是優(yōu)先針對where去設(shè)計(jì)索引?還是優(yōu)先針對order by設(shè)計(jì)索引?

通常情況下都是優(yōu)先針對 where 來設(shè)計(jì)索引,因?yàn)橥ǔG闆r下都是先 where 條件使用索引快速篩選出來符合條件的數(shù)據(jù),然后對進(jìn)行篩選出來的數(shù)據(jù)進(jìn)行排序和分組,而 where 條件快速篩選出來的的數(shù)據(jù)往往不會很多。

對生產(chǎn)實(shí)際運(yùn)行過程中,或者測試環(huán)境大數(shù)據(jù)量測試過程中發(fā)現(xiàn)的慢查詢SQL進(jìn)行特定的索引優(yōu)化、代碼優(yōu)化等策略。

終于輪到實(shí)戰(zhàn)了,小二最喜歡實(shí)戰(zhàn)了。

寫到這里不得不吐槽一下,這個金三銀四的跳槽季節(jié),年前提離職了,結(jié)果離職還沒辦完就封村整整兩個禮拜了,嗚嗚嗚...

上節(jié)小二就提到會有個很有意思的小案例,那么在疫情當(dāng)下,門都出不去的日子,感覺這個例子更有意思了,咱們來討論一下各種社交平臺怎么做的用戶信息搜索呢。

社交平臺有一個小伙伴們都喜歡的功能,搜索好友信息,比如小二熟練的點(diǎn)開省份...城市..性別..年齡..身高...

咳咳咳...小二怎么可能干這種事情,小二的心里只有代碼,嗯...沒錯,就是這樣。

這個就可以說是對于用戶信息的查詢篩選了,通常這種表都是非常大數(shù)據(jù)量的,在不考慮分庫分表的情況下,怎么通過索引配合SQL來優(yōu)化呢?

通常我們在編寫SQL是會寫出類似如下的SQL來執(zhí)行,有 where、order by、limit 等條件來查詢。

那么接下來小二一個一個慢慢增加字段來分析分析,怎么根據(jù)業(yè)務(wù)場景來設(shè)計(jì)索引。

針對這種情況,很簡單,設(shè)計(jì)一個聯(lián)合索引 (provice, city, sex) 就完事了。

那么這時候有小伙伴就會說了,很簡單啊,范圍字段放最后咱還是知道的,聯(lián)合索引改成 (provice, city, sex, age) 不就可以了。

嗯,是的,這么干沒毛病,但是小伙伴們有沒有想過有些人萬一既喜歡帥哥又喜歡美女,別想歪了哈...,挺多小姐姐就既喜歡帥哥又喜歡美女的。

那么這個時候小姐姐就不搜索性別了,那么這個時候聯(lián)合索引只能用到前兩個字段了,那么不符合咱們的專業(yè)標(biāo)準(zhǔn)啊,咋辦呢?這時候還是有辦法的,咱們只需要動動小腦袋改改SQL就行了,在沒有選擇性別時判斷一下,改成下面這樣就可以了。

咋辦嘞,同樣往聯(lián)合索引里面塞,例如 (provice, city, sex, hobby, xx, age) 。

針對這種多個范圍查詢的話,為了比較好的利用索引,在業(yè)務(wù)允許的情況下可以使用固定范圍,然后數(shù)據(jù)庫字段存儲范圍標(biāo)識就可以了,這樣就轉(zhuǎn)化為了等值匹配,就可以很好地利用索引了。

例如最后登錄時間字段不記錄最后登錄時間,而是記錄設(shè)置字段 is_login_within_seven_days 在7天內(nèi)有登錄則為1,否則為0,最后索引設(shè)計(jì)成 (provice, city, sex, hobby, xx, is_login_within_seven_days, age) 。

那么根據(jù)場景最后設(shè)計(jì)出來的這個索引可能已經(jīng)可以覆蓋大部分的查詢流量了,那么如果還有其他一部分熱度比較高的查詢怎么辦呢,辦法也很簡單啊,再加一兩個索引即可。

例如通常會查詢這個城市比較受歡迎(評分:score)的小姐姐,這時候添加一個聯(lián)合索引 (provice, city, sex, score) 那么就可以了。

可以看出,索引時必須結(jié)合場景來設(shè)計(jì)的,思路就是盡量用不超過3個復(fù)雜的聯(lián)合索引來抗住大部分的80%以上的常用查詢流量,然后再用一兩個二級索引來抗下一些非常用查詢流量。

以上就是小二要給大家分享的索引設(shè)計(jì),如果能動動你發(fā)財(cái)?shù)男∈纸o小二點(diǎn)個免費(fèi)的贊就更好啦~

下篇小二就來講講MySQL事務(wù)和鎖機(jī)制。

mysql 優(yōu)化包括哪些內(nèi)容?

mysql的優(yōu)化大的有兩方面:

1、配置優(yōu)化

配置的優(yōu)化其實(shí)包含兩個方面的:操作系統(tǒng)內(nèi)核的優(yōu)化和mysql配置文件的優(yōu)化

1)系統(tǒng)內(nèi)核的優(yōu)化對專用的mysql服務(wù)器來說,無非是內(nèi)存實(shí)用、連接數(shù)、超時處理、TCP處理等方面的優(yōu)化,根據(jù)自己的硬件配置來進(jìn)行優(yōu)化,這里不多講;

2)mysql配置的優(yōu)化,一般來說包含:IO處理的常用參數(shù)、最大連接數(shù)設(shè)置、緩存使用參數(shù)的設(shè)置、慢日志的參數(shù)的設(shè)置、innodb相關(guān)參數(shù)的設(shè)置等,如果有主從關(guān)系在設(shè)置主從同步的相關(guān)參數(shù)即可,網(wǎng)上的相關(guān)配置文件很多,大同小異,常用的設(shè)置大多修改這些差不多就夠用了。

2、sql語句的優(yōu)化

1) ?盡量稍作計(jì)算

Mysql的作用是用來存取數(shù)據(jù)的,不是做計(jì)算的,做計(jì)算的話可以用其他方法去實(shí)現(xiàn),mysql做計(jì)算是很耗資源的。

2)盡量少 join

MySQL 的優(yōu)勢在于簡單,但這在某些方面其實(shí)也是其劣勢。MySQL 優(yōu)化器效率高,但是由于其統(tǒng)計(jì)信息的量有限,優(yōu)化器工作過程出現(xiàn)偏差的可能性也就更多。對于復(fù)雜的多表 Join,一方面由于其優(yōu)化器受限,再者在 Join 這方面所下的功夫還不夠,所以性能表現(xiàn)離 Oracle 等關(guān)系型數(shù)據(jù)庫前輩還是有一定距離。但如果是簡單的單表查詢,這一差距就會極小甚至在有些場景下要優(yōu)于這些數(shù)據(jù)庫前輩

3)盡量少排序

排序操作會消耗較多的 CPU 資源,所以減少排序可以在緩存命中率高等 IO 能力足夠的場景下會較大影響 SQL的響應(yīng)時間。

對于MySQL來說,減少排序有多種辦法,比如:

通過利用索引來排序的方式進(jìn)行優(yōu)化

減少參與排序的記錄條數(shù)

非必要不對數(shù)據(jù)進(jìn)行排序

4)盡量避免 select *

在數(shù)據(jù)量少并且訪問量不大的情況下,select * 沒有什么影響,但是量級達(dá)到一定級別的時候,在執(zhí)行效率和IO資源的使用上,還是有很大關(guān)系的,用什么字段取什么字段,減少不必要的資源浪費(fèi)。

5)盡量用 join 代替子查詢

雖然 Join 性能并不佳,但是和 MySQL 的子查詢比起來還是有非常大的性能優(yōu)勢。MySQL 的子查詢執(zhí)行計(jì)劃一直存在較大的問題,雖然這個問題已經(jīng)存在多年,但是到目前已經(jīng)發(fā)布的所有穩(wěn)定版本中都普遍存在,一直沒有太大改善。雖然官方也在很早就承認(rèn)這一問題,并且承諾盡快解決,但是至少到目前為止我們還沒有看到哪一個版本較好的解決了這一問題。

MySQL RANGE優(yōu)化

范圍訪問方法使用一個索引來檢索包含一個或多個索引間隔中的表行的子集。它可以使用索引中的一列或者多列,以下各節(jié)描述了優(yōu)化器使用范圍訪問的條件

對于一個單列索引,索引值間隔可以方便地由 WHERE 條件中的相應(yīng)條件表示,表示為范圍條件而不是 intervals 。

上述的 常量 指以下情況之一:

以下是在 WHERE 子句中具有范圍條件的查詢示例

一些非常量可能會在優(yōu)化器傳播階段轉(zhuǎn)換為常量

MySQL對于每個可能使用的索引,嘗試從 WHERE 子句中提取范圍條件。在提取過程中,不能用于構(gòu)建條件范圍的條件被刪除,產(chǎn)生重復(fù)范圍的條件被合并,產(chǎn)生空范圍的條件被刪除。

假設(shè)有以下語句, key1 是一個被索引的列,而 nonkey 沒有索引

提取 key1 索引的過程如下:

通常,范圍掃描使用的條件比 WHERE 子句中的限制要少()。MySQL執(zhí)行額外的檢查來過濾滿足范圍條件但是不完全滿足 WHERE 子句的行。

范圍條件提取算法可以處理任意深度嵌套的 AND/OR 構(gòu)造,并且它的輸出不取決于條件在 WHERE 子句中出現(xiàn)的順序

MySQL不支持為空間索引的 range 訪問合并多個范圍。要解決此限制,可以在相同的 SELECT 語句中使用 UNION 語句,將每個空間謂詞放在不同的 SELECT 中。

多列索引的范圍條件是單列索引的擴(kuò)展,多列索引的范圍條件將索引行限制在一個或多個索引元組的間隔中。索引元組間隔是一個按照索引順序的,索引元組的集合。

假設(shè)有一個多列索引 key1(key_part1,key_part2,key_part3) ,按照索引順序,具有以下鍵值元組列表

key_part1 = 1 定義了一個間隔: (1,-inf,-inf) = (key_part1,key_part2,key_part3) (1,+inf,+inf) ,這個間隔包括上面的第4、5、6個元組并且可以被用來進(jìn)行范圍訪問。

但是, key_part3 = 'abc' 沒有定義間隔并且不能被范圍訪問方法使用。

就是索引的最左前綴原則,B樹索引是有序的,多列索引是首先按照第一列進(jìn)行排序,然后在第一列排序的基礎(chǔ)上,再對第二列數(shù)據(jù)進(jìn)行排序,所以后面的列的順序獨(dú)立來看不是有序的,就不能單獨(dú)用后面的列來進(jìn)行排序或者范圍訪問的操作。

對于 HASH 索引,只能使用包含相同值的每個間隔。這意味著只能針對以下形式的條件生成間隔:

這里, const1,const2... 是常量, cmp 是比較表達(dá)式: =,=,IS NULL ,并且條件覆蓋所有的索引部分(就是說,如果有 N 個條件,那么每個條件都需要是一個 N列 索引的一部分)。例如:以下是一個三列 HASH 索引的一個范圍條件

對于 BTREE 索引,一個間隔可以是使用 AND 組成的多個范圍條件的集合,每個條件都將索引的一部分和一個常量使用 =,=,IS NULL,,,=,=,!=,,BETWEENT,LIKE 'pattern'(pattern不以通配符開始) 進(jìn)行比較。只要可以確定與條件匹配的一個索引元組,就可以使用一個間隔( !=, 使用兩個間隔)

當(dāng)比較運(yùn)算符是 =,=,IS NULL 時,優(yōu)化器嘗試使用索引的其他部分來確定間隔。如果比較運(yùn)算符是 , , =, =, !=, , BETWEEN, LIKE ,優(yōu)化器使用索引,但不考慮索引中的其他列。

對于以下表達(dá)式,優(yōu)化器使用第一個 = ,也會使用第二個 = ,但是忽略其他索引部分,并且不將第三部分用作間隔構(gòu)造。

key_part1 = 'foo' AND key_part2 = 10 AND key_part3 10

單個間隔為:

創(chuàng)建的間隔中可能包括比原始條件更多的行,比如,前面這個間隔可能會包括 ('foo',11,0) 這個值, 010 ,這個值不滿足原始條件

如果覆蓋間隔中的行集合的條件使用 OR 進(jìn)行組合,則他們會形成間隔的并集。

如果條件使用 AND 進(jìn)行組合,他們形成一個包括間隔交集的行集合。

示例:

這個在兩列索引上的條件:

(key_part1 = 1 AND key_part2 2) OR (key_part1 5)

間隔是:

可以查看 EXPLAIN 輸出中的 key_len 部分查看使用的索引前綴的最大長度。

在某些情況下, key_len 包括已使用的索引列,但是這個列可能不是你期望的,假設(shè) key_part1 和 key_part2 可以為 NULL ,然后, key_len 顯示以下條件的兩個索引部分長度:

key_part1 = 1 AND key_part2 2

但是實(shí)際上,這個條件被轉(zhuǎn)換為:

key_part1 = 1 AND key_part2 IS NOT NULL

假設(shè)以下表達(dá)式, col_name 是一個索引的列

只要 col_name 等同于這些值中的任意一個,這個表達(dá)式結(jié)果就是 true 。這種比較是等值范圍比較(其中的“范圍”是一個單獨(dú)的值)。

優(yōu)化器按照以下方法,估算讀取相等的值來進(jìn)行等值范圍比較的成本:

當(dāng)使用 index dive 時,優(yōu)化器在每個范圍的末端進(jìn)行 dive 并且使用該范圍中的行數(shù)作為估算值。例如: col_name IN (10, 20, 30) 具有三個等值范圍,優(yōu)化器對每個范圍進(jìn)行兩次 dive 以生成估算值。每次 dive 都會得出具有給定值的行數(shù)的估算值。

使用 index dive 提供了準(zhǔn)確的行數(shù)估算值,但是隨著表達(dá)式中要比較的值的數(shù)量增加,優(yōu)化器需要使用更長的時間來生成行數(shù)的估算值。而使用索引統(tǒng)計(jì)信息的準(zhǔn)確性不如直接使用索引,但是可以對大表進(jìn)行更快的估算。

eq_range_index_dive_limit 選項(xiàng)可以控制優(yōu)化器選擇評估策略的值。要對 N 個等值范圍使用 index dive ,將 eq_range_index_dive_limit 設(shè)置為 N+1 ,要禁用統(tǒng)計(jì)信息,總是使用 index dive ,將 eq_range_index_dive_limit 設(shè)置為0。

在MySQL8.0以前,除了使用 eq_range_index_dive_limit ,沒有其他方法可以跳過 index dive 。在MySQL8.0中,當(dāng)滿足以下條件時,跳過 index dive :

對于 EXPLAIN FOR CONNECTION ,如果跳過了 index dive ,輸出結(jié)果有所變更:

不包括 FOR CONNECTION 的 EXPLAIN 輸出沒有變化

在執(zhí)行跳過 index dive 的查詢后, INFORMATION_SCHEMA.OPTIMIZER_TRACE 表包含一個值為 skipped_due_to_force_index 的 index_dives_for_range_access 行

優(yōu)化器可以對這種形式的查詢進(jìn)行范圍掃描:

SELECT ... FROM t1 WHERE ( col_1, col_2 ) IN (( 'a', 'b' ), ( 'c', 'd' ));

要使用范圍掃描,查詢必須滿足以下條件:

要控制有多少內(nèi)存可以用來進(jìn)行范圍優(yōu)化,使用 range_optimizer_max_mem_size 變量

使用以下原則估算范圍掃描使用的內(nèi)存:

IN() 中的每個值被當(dāng)做使用 OR 結(jié)合的一個謂詞。如果有兩個 IN() 列表,每個列表中都是列表中的值的數(shù)量個謂詞通過 OR 結(jié)合。在這種情況下,視作 M × N 個 謂詞通過OR 結(jié)合。


文章名稱:mysql多字段怎么優(yōu)化,mysql數(shù)據(jù)庫優(yōu)化的幾種方式
文章鏈接:http://weahome.cn/article/phsjce.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部