日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

Mysql原理篇之索引不懂不要瞎用---04

發(fā)布時(shí)間:2023/12/20 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mysql原理篇之索引不懂不要瞎用---04 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Mysql原理篇之索引不懂不要瞎用---04

    • 索引的代價(jià)
    • B+樹(shù)索引適用的條件
      • 全值匹配
      • 匹配左邊的列
      • 匹配列前綴
      • 匹配范圍值
      • 精確匹配某一列并范圍匹配另外一列
      • 用于排序
        • 使用聯(lián)合索引進(jìn)行排序注意事項(xiàng)
        • 不可以使用索引進(jìn)行排序的幾種情況
          • ASC、DESC混用
          • 排序列包含非同一個(gè)索引的列
          • 排序列使用了復(fù)雜的表達(dá)式
      • 用于分組
    • 回表的代價(jià)
      • 覆蓋索引
    • 如何挑選索引
      • 只為用于搜索、排序或分組的列創(chuàng)建索引
      • 考慮列的基數(shù)
      • 索引列的類(lèi)型盡量小
      • 索引字符串值的前綴
        • 索引列前綴對(duì)排序的影響
      • 讓索引列在比較表達(dá)式中單獨(dú)出現(xiàn)
      • 主鍵插入順序
      • 冗余和重復(fù)索引
    • 總結(jié)


我們前邊詳細(xì)、詳細(xì)又詳細(xì)的嘮叨了InnoDB存儲(chǔ)引擎的B+樹(shù)索引,我們必須熟悉下邊這些結(jié)論:

  • 每個(gè)索引都對(duì)應(yīng)一棵B+樹(shù),B+樹(shù)分為好多層,最下邊一層是葉子節(jié)點(diǎn),其余的是內(nèi)節(jié)點(diǎn)。所有用戶記錄都存儲(chǔ)在B+樹(shù)的葉子節(jié)點(diǎn),所有目錄項(xiàng)記錄都存儲(chǔ)在內(nèi)節(jié)點(diǎn)。
  • InnoDB存儲(chǔ)引擎會(huì)自動(dòng)為主鍵(如果沒(méi)有它會(huì)自動(dòng)幫我們添加)建立聚簇索引,聚簇索引的葉子節(jié)點(diǎn)包含完整的用戶記錄。
  • 我們可以為自己感興趣的列建立二級(jí)索引,二級(jí)索引的葉子節(jié)點(diǎn)包含的用戶記錄由索引列 + 主鍵組成,所以如果想通過(guò)二級(jí)索引來(lái)查找完整的用戶記錄的話,需要通過(guò)回表操作,也就是在通過(guò)二級(jí)索引找到主鍵值之后再到聚簇索引中查找完整的用戶記錄。
  • B+樹(shù)中每層節(jié)點(diǎn)都是按照索引列值從小到大的順序排序而組成了雙向鏈表,而且每個(gè)頁(yè)內(nèi)的記錄(不論是用戶記錄還是目錄項(xiàng)記錄)都是按照索引列的值從小到大的順序而形成了一個(gè)單鏈表。如果是聯(lián)合索引的話,則頁(yè)面和記錄先按照聯(lián)合索引前邊的列排序,如果該列值相同,再按照聯(lián)合索引后邊的列排序。
  • 通過(guò)索引查找記錄是從B+樹(shù)的根節(jié)點(diǎn)開(kāi)始,一層一層向下搜索。由于每個(gè)頁(yè)面都按照索引列的值建立了Page Directory(頁(yè)目錄),所以在這些頁(yè)面中的查找非???。

索引的代價(jià)

在熟悉了B+樹(shù)索引原理之后,本篇文章的主題是嘮叨如何更好的使用索引,雖然索引是個(gè)好東西,可不能亂建,在介紹如何更好的使用索引之前先要了解一下使用這玩意兒的代價(jià),它在空間和時(shí)間上都會(huì)拖后腿:

  • 空間上的代價(jià)

    這個(gè)是顯而易見(jiàn)的,每建立一個(gè)索引都要為它建立一棵B+樹(shù),每一棵B+樹(shù)的每一個(gè)節(jié)點(diǎn)都是一個(gè)數(shù)據(jù)頁(yè),一個(gè)頁(yè)默認(rèn)會(huì)占用16KB的存儲(chǔ)空間,一棵很大的B+樹(shù)由許多數(shù)據(jù)頁(yè)組成,那可是很大的一片存儲(chǔ)空間呢。

  • 時(shí)間上的代價(jià)

    每次對(duì)表中的數(shù)據(jù)進(jìn)行增、刪、改操作時(shí),都需要去修改各個(gè)B+樹(shù)索引。而且我們講過(guò),B+樹(shù)每層節(jié)點(diǎn)都是按照索引列的值從小到大的順序排序而組成了雙向鏈表。不論是葉子節(jié)點(diǎn)中的記錄,還是內(nèi)節(jié)點(diǎn)中的記錄(也就是不論是用戶記錄還是目錄項(xiàng)記錄)都是按照索引列的值從小到大的順序而形成了一個(gè)單向鏈表。而增、刪、改操作可能會(huì)對(duì)節(jié)點(diǎn)和記錄的排序造成破壞,所以存儲(chǔ)引擎需要額外的時(shí)間進(jìn)行一些記錄移位,頁(yè)面分裂、頁(yè)面回收啥的操作來(lái)維護(hù)好節(jié)點(diǎn)和記錄的排序。如果我們建了許多索引,每個(gè)索引對(duì)應(yīng)的B+樹(shù)都要進(jìn)行相關(guān)的維護(hù)操作,這還能不給性能拖后腿么?

所以說(shuō),一個(gè)表上索引建的越多,就會(huì)占用越多的存儲(chǔ)空間,在增刪改記錄的時(shí)候性能就越差。為了能建立又好又少的索引,我們先得學(xué)學(xué)這些索引在哪些條件下起作用的。

B+樹(shù)索引適用的條件

下邊我們將嘮叨許多種讓B+樹(shù)索引發(fā)揮最大效能的技巧和注意事項(xiàng),不過(guò)大家要清楚,所有的技巧都是源自你對(duì)B+樹(shù)索引本質(zhì)的理解,所以如果你還不能保證對(duì)B+樹(shù)索引充分的理解,那么再次建議回過(guò)頭把前邊的內(nèi)容看完了再來(lái),要不然讀文章對(duì)你來(lái)說(shuō)是一種折磨。首先,B+樹(shù)索引并不是萬(wàn)能的,并不是所有的查詢語(yǔ)句都能用到我們建立的索引。下邊介紹幾個(gè)我們可能使用B+樹(shù)索引來(lái)進(jìn)行查詢的情況。為了故事的順利發(fā)展,我們需要先創(chuàng)建一個(gè)表,這個(gè)表是用來(lái)存儲(chǔ)人的一些基本信息的:

CREATE TABLE person_info(id INT NOT NULL auto_increment,name VARCHAR(100) NOT NULL,birthday DATE NOT NULL,phone_number CHAR(11) NOT NULL,country varchar(100) NOT NULL,PRIMARY KEY (id),KEY idx_name_birthday_phone_number (name, birthday, phone_number) );

對(duì)于這個(gè)person_info表我們需要注意兩點(diǎn):

  • 表中的主鍵是id列,它存儲(chǔ)一個(gè)自動(dòng)遞增的整數(shù)。所以InnoDB存儲(chǔ)引擎會(huì)自動(dòng)為id列建立聚簇索引。
  • 我們額外定義了一個(gè)二級(jí)索引idx_name_birthday_phone_number,它是由3個(gè)列組成的聯(lián)合索引。所以在這個(gè)索引對(duì)應(yīng)的B+樹(shù)的葉子節(jié)點(diǎn)處存儲(chǔ)的用戶記錄只保留name、birthday、phone_number這三個(gè)列的值以及主鍵id的值,并不會(huì)保存country列的值。

從這兩點(diǎn)注意中我們可以再次看到,一個(gè)表中有多少索引就會(huì)建立多少棵B+樹(shù),person_info表會(huì)為聚簇索引和idx_name_birthday_phone_number索引建立2棵B+樹(shù)。下邊我們畫(huà)一下索引idx_name_birthday_phone_number的示意圖,不過(guò)既然我們已經(jīng)掌握了InnoDB的B+樹(shù)索引原理,那我們?cè)诋?huà)圖的時(shí)候?yàn)榱俗寛D更加清晰,所以在省略一些不必要的部分,比如記錄的額外信息,各頁(yè)面的頁(yè)號(hào)等等,其中內(nèi)節(jié)點(diǎn)中目錄項(xiàng)記錄的頁(yè)號(hào)信息我們用箭頭來(lái)代替,在記錄結(jié)構(gòu)中只保留name、birthday、phone_number、id這四個(gè)列的真實(shí)數(shù)據(jù)值,所以示意圖就長(zhǎng)這樣:

為了方便大家理解,我們特意標(biāo)明了哪些是內(nèi)節(jié)點(diǎn),哪些是葉子節(jié)點(diǎn)。再次強(qiáng)調(diào)一下,內(nèi)節(jié)點(diǎn)中存儲(chǔ)的是目錄項(xiàng)記錄,葉子節(jié)點(diǎn)中存儲(chǔ)的是用戶記錄(由于不是聚簇索引,所以用戶記錄是不完整的,缺少country列的值)。從圖中可以看出,這個(gè)idx_name_birthday_phone_number索引對(duì)應(yīng)的B+樹(shù)中頁(yè)面和記錄的排序方式就是這樣的:

  • 先按照name列的值進(jìn)行排序。
  • 如果name列的值相同,則按照birthday列的值進(jìn)行排序。
  • 如果birthday列的值也相同,則按照phone_number的值進(jìn)行排序。

這個(gè)排序方式十分、特別、非常、巨、very very very重要,因?yàn)橹灰?yè)面和記錄是排好序的,我們就可以通過(guò)二分法來(lái)快速定位查找。下邊的內(nèi)容都仰仗這個(gè)圖了,大家對(duì)照著圖理解。

全值匹配

如果我們的搜索條件中的列和索引列一致的話,這種情況就稱(chēng)為全值匹配,比方說(shuō)下邊這個(gè)查找語(yǔ)句:

SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday = '1990-09-27' AND phone_number = '15123983239';

我們建立的idx_name_birthday_phone_number索引包含的3個(gè)列在這個(gè)查詢語(yǔ)句中都展現(xiàn)出來(lái)了。大家可以想象一下這個(gè)查詢過(guò)程:

  • 因?yàn)锽+樹(shù)的數(shù)據(jù)頁(yè)和記錄先是按照name列的值進(jìn)行排序的,所以先可以很快定位name列的值是Ashburn的記錄位置。
  • 在name列相同的記錄里又是按照birthday列的值進(jìn)行排序的,所以在name列的值是Ashburn的記錄里又可以快速定位birthday列的值是'1990-09-27'的記錄。
  • 如果很不幸,name和birthday列的值都是相同的,那記錄是按照phone_number列的值排序的,所以聯(lián)合索引中的三個(gè)列都可能被用到。

有的同學(xué)也許有個(gè)疑問(wèn),WHERE子句中的幾個(gè)搜索條件的順序?qū)Σ樵兘Y(jié)果有啥影響么?也就是說(shuō)如果我們調(diào)換name、birthday、phone_number這幾個(gè)搜索列的順序?qū)Σ樵兊膱?zhí)行過(guò)程有影響么?比方說(shuō)寫(xiě)成下邊這樣:

SELECT * FROM person_info WHERE birthday = '1990-09-27' AND phone_number = '15123983239' AND name = 'Ashburn';

答案是:沒(méi)影響哈。MySQL有一個(gè)叫查詢優(yōu)化器的東東,會(huì)分析這些搜索條件并且按照可以使用的索引中列的順序來(lái)決定先使用哪個(gè)搜索條件,后使用哪個(gè)搜索條件。我們后邊兒會(huì)有專(zhuān)門(mén)的章節(jié)來(lái)介紹查詢優(yōu)化器,敬請(qǐng)期待。

匹配左邊的列

其實(shí)在我們的搜索語(yǔ)句中也可以不用包含全部聯(lián)合索引中的列,只包含左邊的就行,比方說(shuō)下邊的查詢語(yǔ)句:

SELECT * FROM person_info WHERE name = 'Ashburn';

或者包含多個(gè)左邊的列也行:

SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday = '1990-09-27';

那為什么搜索條件中必須出現(xiàn)左邊的列才可以使用到這個(gè)B+樹(shù)索引呢?比如下邊的語(yǔ)句就用不到這個(gè)B+樹(shù)索引么?

SELECT * FROM person_info WHERE birthday = '1990-09-27';

是的,的確用不到,因?yàn)锽+樹(shù)的數(shù)據(jù)頁(yè)和記錄先是按照name列的值排序的,在name列的值相同的情況下才使用birthday列進(jìn)行排序,也就是說(shuō)name列的值不同的記錄中birthday的值可能是無(wú)序的。而現(xiàn)在你跳過(guò)name列直接根據(jù)birthday的值去查找,臣妾做不到呀~ 那如果我就想在只使用birthday的值去通過(guò)B+樹(shù)索引進(jìn)行查找咋辦呢?這好辦,你再對(duì)birthday列建一個(gè)B+樹(shù)索引就行了,創(chuàng)建索引的語(yǔ)法不用我嘮叨了吧。

但是需要特別注意的一點(diǎn)是,如果我們想使用聯(lián)合索引中盡可能多的列,搜索條件中的各個(gè)列必須是聯(lián)合索引中從最左邊連續(xù)的列。比方說(shuō)聯(lián)合索引idx_name_birthday_phone_number中列的定義順序是name、birthday、phone_number,如果我們的搜索條件中只有name和phone_number,而沒(méi)有中間的birthday,比方說(shuō)這樣:

SELECT * FROM person_info WHERE name = 'Ashburn' AND phone_number = '15123983239';

這樣只能用到name列的索引,birthday和phone_number的索引就用不上了,因?yàn)閚ame值相同的記錄先按照birthday的值進(jìn)行排序,birthday值相同的記錄才按照phone_number值進(jìn)行排序。

匹配列前綴

我們前邊說(shuō)過(guò)為某個(gè)列建立索引的意思其實(shí)就是在對(duì)應(yīng)的B+樹(shù)的記錄中使用該列的值進(jìn)行排序,比方說(shuō)person_info表上建立的聯(lián)合索引idx_name_birthday_phone_number會(huì)先用name列的值進(jìn)行排序,所以這個(gè)聯(lián)合索引對(duì)應(yīng)的B+樹(shù)中的記錄的name列的排列就是這樣的:

Aaron Aaron ... Aaron Asa Ashburn ... Ashburn Baird Barlow ... Barlow

字符串排序的本質(zhì)就是比較哪個(gè)字符串大一點(diǎn)兒,哪個(gè)字符串小一點(diǎn),比較字符串大小就用到了該列的字符集和比較規(guī)則,這個(gè)我們前邊兒嘮叨過(guò),就不多嘮叨了。這里需要注意的是,一般的比較規(guī)則都是逐個(gè)比較字符的大小,也就是說(shuō)我們比較兩個(gè)字符串的大小的過(guò)程其實(shí)是這樣的:

  • 先比較字符串的第一個(gè)字符,第一個(gè)字符小的那個(gè)字符串就比較小。
  • 如果兩個(gè)字符串的第一個(gè)字符相同,那就再比較第二個(gè)字符,第二個(gè)字符比較小的那個(gè)字符串就比較小。
  • 如果兩個(gè)字符串的第二個(gè)字符也相同,那就接著比較第三個(gè)字符,依此類(lèi)推。

所以一個(gè)排好序的字符串列其實(shí)有這樣的特點(diǎn):

  • 先按照字符串的第一個(gè)字符進(jìn)行排序。
  • 如果第一個(gè)字符相同再按照第二個(gè)字符進(jìn)行排序。
  • 如果第二個(gè)字符相同再按照第三個(gè)字符進(jìn)行排序,依此類(lèi)推。

也就是說(shuō)這些字符串的前n個(gè)字符,也就是前綴都是排好序的,所以對(duì)于字符串類(lèi)型的索引列來(lái)說(shuō),我們只匹配它的前綴也是可以快速定位記錄的,比方說(shuō)我們想查詢名字以'As'開(kāi)頭的記錄,那就可以這么寫(xiě)查詢語(yǔ)句:

SELECT * FROM person_info WHERE name LIKE 'As%';

但是需要注意的是,如果只給出后綴或者中間的某個(gè)字符串,比如這樣:

SELECT * FROM person_info WHERE name LIKE '%As%';

MySQL就無(wú)法快速定位記錄位置了,因?yàn)樽址虚g有'As'的字符串并沒(méi)有排好序,所以只能全表掃描了。有時(shí)候我們有一些匹配某些字符串后綴的需求,比方說(shuō)某個(gè)表有一個(gè)url列,該列中存儲(chǔ)了許多url:

+----------------+ | url | +----------------+ | www.baidu.com | | www.google.com | | www.gov.cn | | ... | | www.wto.org | +----------------+

假設(shè)已經(jīng)對(duì)該url列創(chuàng)建了索引,如果我們想查詢以com為后綴的網(wǎng)址的話可以這樣寫(xiě)查詢條件:WHERE url LIKE '%com',但是這樣的話無(wú)法使用該url列的索引。為了在查詢時(shí)用到這個(gè)索引而不至于全表掃描,我們可以把后綴查詢改寫(xiě)成前綴查詢,不過(guò)我們就得把表中的數(shù)據(jù)全部逆序存儲(chǔ)一下,也就是說(shuō)我們可以這樣保存url列中的數(shù)據(jù):

+----------------+ | url | +----------------+ | moc.udiab.www | | moc.elgoog.www | | nc.vog.www | | ... | | gro.otw.www | +----------------+

這樣再查找以com為后綴的網(wǎng)址時(shí)搜索條件便可以這么寫(xiě):WHERE url LIKE 'moc%',這樣就可以用到索引了。

匹配范圍值

回頭看我們idx_name_birthday_phone_number索引的B+樹(shù)示意圖,所有記錄都是按照索引列的值從小到大的順序排好序的,所以這極大的方便我們查找索引列的值在某個(gè)范圍內(nèi)的記錄。比方說(shuō)下邊這個(gè)查詢語(yǔ)句:

SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow';

由于B+樹(shù)中的數(shù)據(jù)頁(yè)和記錄是先按name列排序的,所以我們上邊的查詢過(guò)程其實(shí)是這樣的:

  • 通過(guò)B+樹(shù)在葉子節(jié)點(diǎn)中找到第一條name值大于Asa的二級(jí)索引記錄,讀取該記錄的主鍵值進(jìn)行回表操作,獲得對(duì)應(yīng)的聚簇索引記錄后發(fā)送給客戶端。
  • 根據(jù)上一步找到的記錄,沿著記錄所在的鏈表向后查找(同一頁(yè)面中的記錄使用單向鏈表連接起來(lái),數(shù)據(jù)頁(yè)之間用雙向鏈表連接起來(lái))下一條二級(jí)索引記錄,判斷該記錄是否符合name < 'Barlow’條件,如果符合,則進(jìn)行回表操作后發(fā)送至客戶端。
  • 重復(fù)上一步驟,直到某條二級(jí)索引記錄不符合name <'Barlow’條件為止。

不過(guò)在使用聯(lián)合進(jìn)行范圍查找的時(shí)候需要注意,如果對(duì)多個(gè)列同時(shí)進(jìn)行范圍查找的話,只有對(duì)索引最左邊的那個(gè)列進(jìn)行范圍查找的時(shí)候才能用到B+樹(shù)索引,比方說(shuō)這樣:

SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow' AND birthday > '1980-01-01';

上邊這個(gè)查詢可以分成兩個(gè)部分:

  • 通過(guò)條件name > 'Asa' AND name < 'Barlow' 來(lái)對(duì)name進(jìn)行范圍,查找的結(jié)果可能有多條name值不同的記錄,
  • 對(duì)這些name值不同的記錄繼續(xù)通過(guò)birthday > '1980-01-01'條件繼續(xù)過(guò)濾。
  • 這樣子對(duì)于聯(lián)合索引idx_name_birthday_phone_number來(lái)說(shuō),只能用到name列的部分,而用不到birthday列的部分,因?yàn)橹挥衝ame值相同的情況下才能用birthday列的值進(jìn)行排序,而這個(gè)查詢中通過(guò)name進(jìn)行范圍查找的記錄中可能并不是按照birthday列進(jìn)行排序的,所以在搜索條件中繼續(xù)以birthday列進(jìn)行查找時(shí)是用不到這個(gè)B+樹(shù)索引的。


    精確匹配某一列并范圍匹配另外一列

    對(duì)于同一個(gè)聯(lián)合索引來(lái)說(shuō),雖然對(duì)多個(gè)列都進(jìn)行范圍查找時(shí)只能用到最左邊那個(gè)索引列,但是如果左邊的列是精確查找,則右邊的列可以進(jìn)行范圍查找,比方說(shuō)這樣:

    SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday > '1980-01-01' AND birthday < '2000-12-31' AND phone_number > '15100000000';

    這個(gè)查詢的條件可以分為3個(gè)部分:

  • name = 'Ashburn',對(duì)name列進(jìn)行精確查找,當(dāng)然可以使用B+樹(shù)索引了。
  • birthday > '1980-01-01' AND birthday < '2000-12-31',由于name列是精確查找,所以通過(guò)name = 'Ashburn'條件查找后得到的結(jié)果的name值都是相同的,它們會(huì)再按照birthday的值進(jìn)行排序。所以此時(shí)對(duì)birthday列進(jìn)行范圍查找是可以用到B+樹(shù)索引的。
  • phone_number > '15100000000',通過(guò)birthday的范圍查找的記錄的birthday的值可能不同,所以這個(gè)條件無(wú)法再利用B+樹(shù)索引了,只能遍歷上一步查詢得到的記錄。
  • 同理,下邊的查詢也是可能用到這個(gè)idx_name_birthday_phone_number聯(lián)合索引的:

    SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday = '1980-01-01' AND phone_number > '15100000000';

    用于排序

    我們?cè)趯?xiě)查詢語(yǔ)句的時(shí)候經(jīng)常需要對(duì)查詢出來(lái)的記錄通過(guò)ORDER BY子句按照某種規(guī)則進(jìn)行排序。一般情況下,我們只能把記錄都加載到內(nèi)存中,再用一些排序算法,比如快速排序、歸并排序、吧啦吧啦排序等等在內(nèi)存中對(duì)這些記錄進(jìn)行排序,有的時(shí)候可能查詢的結(jié)果集太大以至于不能在內(nèi)存中進(jìn)行排序的話,還可能暫時(shí)借助磁盤(pán)的空間來(lái)存放中間結(jié)果,排序操作完成后再把排好序的結(jié)果集返回到客戶端。在MySQL中,把這種在內(nèi)存中或者磁盤(pán)上進(jìn)行排序的方式統(tǒng)稱(chēng)為文件排序(英文名:filesort),跟文件這個(gè)詞兒一沾邊兒,就顯得這些排序操作非常慢了(磁盤(pán)和內(nèi)存的速度比起來(lái),就像是飛機(jī)和蝸牛的對(duì)比)。但是如果ORDER BY子句里使用到了我們的索引列,就有可能省去在內(nèi)存或文件中排序的步驟,比如下邊這個(gè)簡(jiǎn)單的查詢語(yǔ)句:

    SELECT * FROM person_info ORDER BY name, birthday, phone_number LIMIT 10;

    這個(gè)查詢的結(jié)果集需要先按照name值排序,如果記錄的name值相同,則需要按照birthday來(lái)排序,如果birthday的值相同,則需要按照phone_number排序。大家可以回過(guò)頭去看我們建立的idx_name_birthday_phone_number索引的示意圖,因?yàn)檫@個(gè)B+樹(shù)索引本身就是按照上述規(guī)則排好序的,所以直接從索引中提取數(shù)據(jù),然后進(jìn)行回表操作取出該索引中不包含的列就好了。簡(jiǎn)單吧?是的,索引就是這么牛逼。

    使用聯(lián)合索引進(jìn)行排序注意事項(xiàng)

    對(duì)于聯(lián)合索引有個(gè)問(wèn)題需要注意,ORDER BY的子句后邊的列的順序也必須按照索引列的順序給出,如果給出ORDER BY phone_number, birthday, name的順序,那也是用不了B+樹(shù)索引,這種顛倒順序就不能使用索引的原因我們上邊詳細(xì)說(shuō)過(guò)了,這就不贅述了。

    同理,ORDER BY name、ORDER BY name, birthday這種匹配索引左邊的列的形式可以使用部分的B+樹(shù)索引。當(dāng)聯(lián)合索引左邊列的值為常量,也可以使用后邊的列進(jìn)行排序,比如這樣:

    SELECT * FROM person_info WHERE name = 'A' ORDER BY birthday, phone_number LIMIT 10;

    這個(gè)查詢能使用聯(lián)合索引進(jìn)行排序是因?yàn)閚ame列的值相同的記錄是按照birthday, phone_number排序的,說(shuō)了好多遍了都。

    不可以使用索引進(jìn)行排序的幾種情況

    ASC、DESC混用

    對(duì)于使用聯(lián)合索引進(jìn)行排序的場(chǎng)景,我們要求各個(gè)排序列的排序順序是一致的,也就是要么各個(gè)列都是ASC規(guī)則排序,要么都是DESC規(guī)則排序。

    小貼士:ORDER BY子句后的列如果不加ASC或者DESC默認(rèn)是按照ASC排序規(guī)則排序的,也就是升序排序的。

    為啥會(huì)有這種奇葩規(guī)定呢?這個(gè)還得回頭想想這個(gè)idx_name_birthday_phone_number聯(lián)合索引中記錄的結(jié)構(gòu):

    • 先按照記錄的name列的值進(jìn)行升序排列。
    • 如果記錄的name列的值相同,再按照birthday列的值進(jìn)行升序排列。
    • 如果記錄的birthday列的值相同,再按照phone_number列的值進(jìn)行升序排列。

    如果查詢中的各個(gè)排序列的排序順序是一致的,比方說(shuō)下邊這兩種情況:

    • ORDER BY name, birthday LIMIT 10

      這種情況直接從索引的最左邊開(kāi)始往右讀10行記錄就可以了。

    • ORDER BY name DESC, birthday DESC LIMIT 10,

      這種情況直接從索引的最右邊開(kāi)始往左讀10行記錄就可以了。

    但是如果我們查詢的需求是先按照name列進(jìn)行升序排列,再按照birthday列進(jìn)行降序排列的話,比如說(shuō)這樣的查詢語(yǔ)句:

    SELECT * FROM person_info ORDER BY name, birthday DESC LIMIT 10;

    這樣如果使用索引排序的話過(guò)程就是這樣的:

    • 先從索引的最左邊確定name列最小的值,然后找到name列等于該值的所有記錄,然后從name列等于該值的最右邊的那條記錄開(kāi)始往左找10條記錄。
    • 如果name列等于最小的值的記錄不足10條,再繼續(xù)往右找name值第二小的記錄,重復(fù)上邊那個(gè)過(guò)程,直到找到10條記錄為止。

    累不累?累!重點(diǎn)是這樣不能高效使用索引,而要采取更復(fù)雜的算法去從索引中取數(shù)據(jù),設(shè)計(jì)MySQL的大叔覺(jué)得這樣還不如直接文件排序來(lái)的快,所以就規(guī)定使用聯(lián)合索引的各個(gè)排序列的排序順序必須是一致的。

    排序列包含非同一個(gè)索引的列

    有時(shí)候用來(lái)排序的多個(gè)列不是一個(gè)索引里的,這種情況也不能使用索引進(jìn)行排序,比方說(shuō):

    SELECT * FROM person_info ORDER BY name, country LIMIT 10;

    name和country并不屬于一個(gè)聯(lián)合索引中的列,所以無(wú)法使用索引進(jìn)行排序,至于為啥我就不想再?lài)Z叨了,自己用前邊的理論自己捋一捋吧~

    排序列使用了復(fù)雜的表達(dá)式

    要想使用索引進(jìn)行排序操作,必須保證索引列是以單獨(dú)列的形式出現(xiàn),而不是修飾過(guò)的形式,比方說(shuō)這樣:

    SELECT * FROM person_info ORDER BY UPPER(name) LIMIT 10;

    使用了UPPER函數(shù)修飾過(guò)的列就不是單獨(dú)的列啦,這樣就無(wú)法使用索引進(jìn)行排序啦。

    用于分組

    有時(shí)候我們?yōu)榱朔奖憬y(tǒng)計(jì)表中的一些信息,會(huì)把表中的記錄按照某些列進(jìn)行分組。比如下邊這個(gè)分組查詢:

    SELECT name, birthday, phone_number, COUNT(*) FROM person_info GROUP BY name, birthday, phone_number

    這個(gè)查詢語(yǔ)句相當(dāng)于做了3次分組操作:

  • 先把記錄按照name值進(jìn)行分組,所有name值相同的記錄劃分為一組。
  • 將每個(gè)name值相同的分組里的記錄再按照birthday的值進(jìn)行分組,將birthday值相同的記錄放到一個(gè)小分組里,所以看起來(lái)就像在一個(gè)大分組里又化分了好多小分組。
  • 再將上一步中產(chǎn)生的小分組按照phone_number的值分成更小的分組,所以整體上看起來(lái)就像是先把記錄分成一個(gè)大分組,然后把大分組分成若干個(gè)小分組,然后把若干個(gè)小分組再細(xì)分成更多的小小分組。
  • 然后針對(duì)那些小小分組進(jìn)行統(tǒng)計(jì),比如在我們這個(gè)查詢語(yǔ)句中就是統(tǒng)計(jì)每個(gè)小小分組包含的記錄條數(shù)。如果沒(méi)有索引的話,這個(gè)分組過(guò)程全部需要在內(nèi)存里實(shí)現(xiàn),而如果有了索引的話,恰巧這個(gè)分組順序又和我們的B+樹(shù)中的索引列的順序是一致的,而我們的B+樹(shù)索引又是按照索引列排好序的,這不正好么,所以可以直接使用B+樹(shù)索引進(jìn)行分組。

    和使用B+樹(shù)索引進(jìn)行排序是一個(gè)道理,分組列的順序也需要和索引列的順序一致,也可以只使用索引列中左邊的列進(jìn)行分組,吧啦吧啦的~


    回表的代價(jià)

    上邊的討論對(duì)回表這個(gè)詞兒多是一帶而過(guò),可能大家沒(méi)啥深刻的體會(huì),下邊我們?cè)敿?xì)嘮叨下。還是用idx_name_birthday_phone_number索引為例,看下邊這個(gè)查詢:

    SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow';

    在使用idx_name_birthday_phone_number索引進(jìn)行查詢時(shí)大致可以分為這兩個(gè)步驟:

  • 從索引idx_name_birthday_phone_number對(duì)應(yīng)的B+樹(shù)中取出name值在Asa~Barlow之間的用戶記錄。
  • 由于索引idx_name_birthday_phone_number對(duì)應(yīng)的B+樹(shù)用戶記錄中只包含name、birthday、phone_number、id這4個(gè)字段,而查詢列表是*,意味著要查詢表中所有字段,也就是還要包括country字段。這時(shí)需要把從上一步中獲取到的每一條記錄的id字段都到聚簇索引對(duì)應(yīng)的B+樹(shù)中找到完整的用戶記錄,也就是我們通常所說(shuō)的回表,然后把完整的用戶記錄返回給查詢用戶。
  • 由于索引idx_name_birthday_phone_number對(duì)應(yīng)的B+樹(shù)中的記錄首先會(huì)按照name列的值進(jìn)行排序,所以值在Asa~Barlow之間的記錄在磁盤(pán)中的存儲(chǔ)是相連的,集中分布在一個(gè)或幾個(gè)數(shù)據(jù)頁(yè)中,我們可以很快的把這些連著的記錄從磁盤(pán)中讀出來(lái),這種讀取方式我們也可以稱(chēng)為順序I/O。根據(jù)第1步中獲取到的記錄的id字段的值可能并不相連,而在聚簇索引中記錄是根據(jù)id(也就是主鍵)的順序排列的,所以根據(jù)這些并不連續(xù)的id值到聚簇索引中訪問(wèn)完整的用戶記錄可能分布在不同的數(shù)據(jù)頁(yè)中,這樣讀取完整的用戶記錄可能要訪問(wèn)更多的數(shù)據(jù)頁(yè),這種讀取方式我們也可以稱(chēng)為隨機(jī)I/O。一般情況下,順序I/O比隨機(jī)I/O的性能高很多,所以步驟1的執(zhí)行可能很快,而步驟2就慢一些。所以這個(gè)使用索引idx_name_birthday_phone_number的查詢有這么兩個(gè)特點(diǎn):

    • 會(huì)使用到兩個(gè)B+樹(shù)索引,一個(gè)二級(jí)索引,一個(gè)聚簇索引。
    • 訪問(wèn)二級(jí)索引使用順序I/O,訪問(wèn)聚簇索引使用隨機(jī)I/O。

    需要回表的記錄越多,使用二級(jí)索引的性能就越低,甚至讓某些查詢寧愿使用全表掃描也不使用二級(jí)索引。比方說(shuō)name值在Asa~Barlow之間的用戶記錄數(shù)量占全部記錄數(shù)量90%以上,那么如果使用idx_name_birthday_phone_number索引的話,有90%多的id值需要回表,這不是吃力不討好么,還不如直接去掃描聚簇索引(也就是全表掃描)。

    那什么時(shí)候采用全表掃描的方式,什么時(shí)候使用采用二級(jí)索引 + 回表的方式去執(zhí)行查詢呢?這個(gè)就是傳說(shuō)中的查詢優(yōu)化器做的工作,查詢優(yōu)化器會(huì)事先對(duì)表中的記錄計(jì)算一些統(tǒng)計(jì)數(shù)據(jù),然后再利用這些統(tǒng)計(jì)數(shù)據(jù)根據(jù)查詢的條件來(lái)計(jì)算一下需要回表的記錄數(shù),需要回表的記錄數(shù)越多,就越傾向于使用全表掃描,反之傾向于使用二級(jí)索引 + 回表的方式。當(dāng)然優(yōu)化器做的分析工作不僅僅是這么簡(jiǎn)單,但是大致上是個(gè)這個(gè)過(guò)程。一般情況下,限制查詢獲取較少的記錄數(shù)會(huì)讓優(yōu)化器更傾向于選擇使用二級(jí)索引 + 回表的方式進(jìn)行查詢,因?yàn)榛乇淼挠涗浽缴?#xff0c;性能提升就越高,比方說(shuō)上邊的查詢可以改寫(xiě)成這樣:

    SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow' LIMIT 10;

    添加了LIMIT 10的查詢更容易讓優(yōu)化器采用二級(jí)索引 + 回表的方式進(jìn)行查詢。

    對(duì)于有排序需求的查詢,上邊討論的采用全表掃描還是二級(jí)索引 + 回表的方式進(jìn)行查詢的條件也是成立的,比方說(shuō)下邊這個(gè)查詢:

    SELECT * FROM person_info ORDER BY name, birthday, phone_number;

    由于查詢列表是*,所以如果使用二級(jí)索引進(jìn)行排序的話,需要把排序完的二級(jí)索引記錄全部進(jìn)行回表操作,這樣操作的成本還不如直接遍歷聚簇索引然后再進(jìn)行文件排序(filesort)低,所以優(yōu)化器會(huì)傾向于使用全表掃描的方式執(zhí)行查詢。如果我們加了LIMIT子句,比如這樣:

    SELECT * FROM person_info ORDER BY name, birthday, phone_number LIMIT 10;

    這樣需要回表的記錄特別少,優(yōu)化器就會(huì)傾向于使用二級(jí)索引 + 回表的方式執(zhí)行查詢。

    覆蓋索引

    為了徹底告別回表操作帶來(lái)的性能損耗,我們建議:最好在查詢列表里只包含索引列,比如這樣:

    SELECT name, birthday, phone_number FROM person_info WHERE name > 'Asa' AND name < 'Barlow'

    因?yàn)槲覀冎徊樵僴ame, birthday, phone_number這三個(gè)索引列的值,所以在通過(guò)idx_name_birthday_phone_number索引得到結(jié)果后就不必到聚簇索引中再查找記錄的剩余列,也就是country列的值了,這樣就省去了回表操作帶來(lái)的性能損耗。我們把這種只需要用到索引的查詢方式稱(chēng)為索引覆蓋。排序操作也優(yōu)先使用覆蓋索引的方式進(jìn)行查詢,比方說(shuō)這個(gè)查詢:

    SELECT name, birthday, phone_number FROM person_info ORDER BY name, birthday, phone_number;

    雖然這個(gè)查詢中沒(méi)有LIMIT子句,但是采用了覆蓋索引,所以查詢優(yōu)化器就會(huì)直接使用idx_name_birthday_phone_number索引進(jìn)行排序而不需要回表操作了。

    當(dāng)然,如果業(yè)務(wù)需要查詢出索引以外的列,那還是以保證業(yè)務(wù)需求為重。但是我們很不鼓勵(lì)用*號(hào)作為查詢列表,最好把我們需要查詢的列依次標(biāo)明。


    如何挑選索引

    上邊我們以idx_name_birthday_phone_number索引為例對(duì)索引的適用條件進(jìn)行了詳細(xì)的嘮叨,下邊看一下我們?cè)诮⑺饕龝r(shí)或者編寫(xiě)查詢語(yǔ)句時(shí)就應(yīng)該注意的一些事項(xiàng)。

    只為用于搜索、排序或分組的列創(chuàng)建索引

    也就是說(shuō),只為出現(xiàn)在WHERE子句中的列、連接子句中的連接列,或者出現(xiàn)在ORDER BY或GROUP BY子句中的列創(chuàng)建索引。而出現(xiàn)在查詢列表中的列就沒(méi)必要建立索引了:

    SELECT birthday, country FROM person_name WHERE name = 'Ashburn';

    像查詢列表中的birthday、country這兩個(gè)列就不需要建立索引,我們只需要為出現(xiàn)在WHERE子句中的name列創(chuàng)建索引就可以了。

    考慮列的基數(shù)

    列的基數(shù)指的是某一列中不重復(fù)數(shù)據(jù)的個(gè)數(shù),比方說(shuō)某個(gè)列包含值2, 5, 8, 2, 5, 8, 2, 5, 8,雖然有9條記錄,但該列的基數(shù)卻是3。也就是說(shuō),在記錄行數(shù)一定的情況下,列的基數(shù)越大,該列中的值越分散,列的基數(shù)越小,該列中的值越集中。這個(gè)列的基數(shù)指標(biāo)非常重要,直接影響我們是否能有效的利用索引。假設(shè)某個(gè)列的基數(shù)為1,也就是所有記錄在該列中的值都一樣,那為該列建立索引是沒(méi)有用的,因?yàn)樗兄刀家粯泳蜔o(wú)法排序,無(wú)法進(jìn)行快速查找了~ 而且如果某個(gè)建立了二級(jí)索引的列的重復(fù)值特別多,那么使用這個(gè)二級(jí)索引查出的記錄還可能要做回表操作,這樣性能損耗就更大了。所以結(jié)論就是:最好為那些列的基數(shù)大的列建立索引,為基數(shù)太小列的建立索引效果可能不好。

    索引列的類(lèi)型盡量小

    我們?cè)诙x表結(jié)構(gòu)的時(shí)候要顯式的指定列的類(lèi)型,以整數(shù)類(lèi)型為例,有TINYINT、MEDIUMINT、INT、BIGINT這么幾種,它們占用的存儲(chǔ)空間依次遞增,我們這里所說(shuō)的類(lèi)型大小指的就是該類(lèi)型表示的數(shù)據(jù)范圍的大小。能表示的整數(shù)范圍當(dāng)然也是依次遞增,如果我們想要對(duì)某個(gè)整數(shù)列建立索引的話,在表示的整數(shù)范圍允許的情況下,盡量讓索引列使用較小的類(lèi)型,比如我們能使用INT就不要使用BIGINT,能使用MEDIUMINT就不要使用INT~ 這是因?yàn)?#xff1a;

    • 數(shù)據(jù)類(lèi)型越小,在查詢時(shí)進(jìn)行的比較操作越快(這是CPU層次的東東)
    • 數(shù)據(jù)類(lèi)型越小,索引占用的存儲(chǔ)空間就越少,在一個(gè)數(shù)據(jù)頁(yè)內(nèi)就可以放下更多的記錄,從而減少磁盤(pán)I/O帶來(lái)的性能損耗,也就意味著可以把更多的數(shù)據(jù)頁(yè)緩存在內(nèi)存中,從而加快讀寫(xiě)效率。

    這個(gè)建議對(duì)于表的主鍵來(lái)說(shuō)更加適用,因?yàn)椴粌H是聚簇索引中會(huì)存儲(chǔ)主鍵值,其他所有的二級(jí)索引的節(jié)點(diǎn)處都會(huì)存儲(chǔ)一份記錄的主鍵值,如果主鍵適用更小的數(shù)據(jù)類(lèi)型,也就意味著節(jié)省更多的存儲(chǔ)空間和更高效的I/O。

    索引字符串值的前綴

    我們知道一個(gè)字符串其實(shí)是由若干個(gè)字符組成,如果我們?cè)贛ySQL中使用utf8字符集去存儲(chǔ)字符串的話,編碼一個(gè)字符需要占用1~3個(gè)字節(jié)。假設(shè)我們的字符串很長(zhǎng),那存儲(chǔ)一個(gè)字符串就需要占用很大的存儲(chǔ)空間。在我們需要為這個(gè)字符串列建立索引時(shí),那就意味著在對(duì)應(yīng)的B+樹(shù)中有這么兩個(gè)問(wèn)題:

    • B+樹(shù)索引中的記錄需要把該列的完整字符串存儲(chǔ)起來(lái),而且字符串越長(zhǎng),在索引中占用的存儲(chǔ)空間越大。
    • 如果B+樹(shù)索引中索引列存儲(chǔ)的字符串很長(zhǎng),那在做字符串比較時(shí)會(huì)占用更多的時(shí)間。

    我們前邊兒說(shuō)過(guò)索引列的字符串前綴其實(shí)也是排好序的,所以索引的設(shè)計(jì)者提出了個(gè)方案 — 只對(duì)字符串的前幾個(gè)字符進(jìn)行索引也就是說(shuō)在二級(jí)索引的記錄中只保留字符串前幾個(gè)字符。這樣在查找記錄時(shí)雖然不能精確的定位到記錄的位置,但是能定位到相應(yīng)前綴所在的位置,然后根據(jù)前綴相同的記錄的主鍵值回表查詢完整的字符串值,再對(duì)比就好了。這樣只在B+樹(shù)中存儲(chǔ)字符串的前幾個(gè)字符的編碼,既節(jié)約空間,又減少了字符串的比較時(shí)間,還大概能解決排序的問(wèn)題,何樂(lè)而不為,比方說(shuō)我們?cè)诮ū碚Z(yǔ)句中只對(duì)name列的前10個(gè)字符進(jìn)行索引可以這么寫(xiě):

    CREATE TABLE person_info(name VARCHAR(100) NOT NULL,birthday DATE NOT NULL,phone_number CHAR(11) NOT NULL,country varchar(100) NOT NULL,KEY idx_name_birthday_phone_number (name(10), birthday, phone_number) );

    name(10)就表示在建立的B+樹(shù)索引中只保留記錄的前10個(gè)字符的編碼,這種只索引字符串值的前綴的策略是我們非常鼓勵(lì)的,尤其是在字符串類(lèi)型能存儲(chǔ)的字符比較多的時(shí)候。

    索引列前綴對(duì)排序的影響

    如果使用了索引列前綴,比方說(shuō)前邊只把name列的前10個(gè)字符放到了二級(jí)索引中,下邊這個(gè)查詢可能就有點(diǎn)兒尷尬了:

    SELECT * FROM person_info ORDER BY name LIMIT 10;

    因?yàn)槎?jí)索引中不包含完整的name列信息,所以無(wú)法對(duì)前十個(gè)字符相同,后邊的字符不同的記錄進(jìn)行排序,也就是使用索引列前綴的方式無(wú)法支持使用索引排序,只好乖乖的用文件排序嘍。

    讓索引列在比較表達(dá)式中單獨(dú)出現(xiàn)

    假設(shè)表中有一個(gè)整數(shù)列my_col,我們?yōu)檫@個(gè)列建立了索引。下邊的兩個(gè)WHERE子句雖然語(yǔ)義是一致的,但是在效率上卻有差別:

  • WHERE my_col * 2 < 4
  • WHERE my_col < 4/2
  • 第1個(gè)WHERE子句中my_col列并不是以單獨(dú)列的形式出現(xiàn)的,而是以my_col * 2這樣的表達(dá)式的形式出現(xiàn)的,存儲(chǔ)引擎會(huì)依次遍歷所有的記錄,計(jì)算這個(gè)表達(dá)式的值是不是小于4,所以這種情況下是使用不到為my_col列建立的B+樹(shù)索引的。而第2個(gè)WHERE子句中my_col列并是以單獨(dú)列的形式出現(xiàn)的,這樣的情況可以直接使用B+樹(shù)索引。

    所以結(jié)論就是:如果索引列在比較表達(dá)式中不是以單獨(dú)列的形式出現(xiàn),而是以某個(gè)表達(dá)式,或者函數(shù)調(diào)用形式出現(xiàn)的話,是用不到索引的。

    主鍵插入順序

    我們知道,對(duì)于一個(gè)使用InnoDB存儲(chǔ)引擎的表來(lái)說(shuō),在我們沒(méi)有顯式的創(chuàng)建索引時(shí),表中的數(shù)據(jù)實(shí)際上都是存儲(chǔ)在聚簇索引的葉子節(jié)點(diǎn)的。而記錄又是存儲(chǔ)在數(shù)據(jù)頁(yè)中的,數(shù)據(jù)頁(yè)和記錄又是按照記錄主鍵值從小到大的順序進(jìn)行排序,所以如果我們插入的記錄的主鍵值是依次增大的話,那我們每插滿一個(gè)數(shù)據(jù)頁(yè)就換到下一個(gè)數(shù)據(jù)頁(yè)繼續(xù)插,而如果我們插入的主鍵值忽大忽小的話,這就比較麻煩了,假設(shè)某個(gè)數(shù)據(jù)頁(yè)存儲(chǔ)的記錄已經(jīng)滿了,它存儲(chǔ)的主鍵值在1~100之間:

    如果此時(shí)再插入一條主鍵值為9的記錄,那它插入的位置就如下圖:

    可這個(gè)數(shù)據(jù)頁(yè)已經(jīng)滿了啊,再插進(jìn)來(lái)咋辦呢?我們需要把當(dāng)前頁(yè)面分裂成兩個(gè)頁(yè)面,把本頁(yè)中的一些記錄移動(dòng)到新創(chuàng)建的這個(gè)頁(yè)中。頁(yè)面分裂和記錄移位意味著什么?意味著:性能損耗!所以如果我們想盡量避免這樣無(wú)謂的性能損耗,最好讓插入的記錄的主鍵值依次遞增,這樣就不會(huì)發(fā)生這樣的性能損耗了。所以我們建議:讓主鍵具有AUTO_INCREMENT,讓存儲(chǔ)引擎自己為表生成主鍵,而不是我們手動(dòng)插入 ,比方說(shuō)我們可以這樣定義person_info表:

    CREATE TABLE person_info(id INT UNSIGNED NOT NULL AUTO_INCREMENT,name VARCHAR(100) NOT NULL,birthday DATE NOT NULL,phone_number CHAR(11) NOT NULL,country varchar(100) NOT NULL,PRIMARY KEY (id),KEY idx_name_birthday_phone_number (name(10), birthday, phone_number) );

    我們自定義的主鍵列id擁有AUTO_INCREMENT屬性,在插入記錄時(shí)存儲(chǔ)引擎會(huì)自動(dòng)為我們填入自增的主鍵值。

    冗余和重復(fù)索引

    有時(shí)候有的同學(xué)有意或者無(wú)意的就對(duì)同一個(gè)列創(chuàng)建了多個(gè)索引,比方說(shuō)這樣寫(xiě)建表語(yǔ)句:

    CREATE TABLE person_info(id INT UNSIGNED NOT NULL AUTO_INCREMENT,name VARCHAR(100) NOT NULL,birthday DATE NOT NULL,phone_number CHAR(11) NOT NULL,country varchar(100) NOT NULL,PRIMARY KEY (id),KEY idx_name_birthday_phone_number (name(10), birthday, phone_number),KEY idx_name (name(10)) );

    我們知道,通過(guò)idx_name_birthday_phone_number索引就可以對(duì)name列進(jìn)行快速搜索,再創(chuàng)建一個(gè)專(zhuān)門(mén)針對(duì)name列的索引就算是一個(gè)冗余索引,維護(hù)這個(gè)索引只會(huì)增加維護(hù)的成本,并不會(huì)對(duì)搜索有什么好處。

    另一種情況,我們可能會(huì)對(duì)某個(gè)列重復(fù)建立索引,比方說(shuō)這樣:

    CREATE TABLE repeat_index_demo (c1 INT PRIMARY KEY,c2 INT,UNIQUE uidx_c1 (c1),INDEX idx_c1 (c1) );

    我們看到,c1既是主鍵、又給它定義為一個(gè)唯一索引,還給它定義了一個(gè)普通索引,可是主鍵本身就會(huì)生成聚簇索引,所以定義的唯一索引和普通索引是重復(fù)的,這種情況要避免。


    總結(jié)

    上邊只是我們?cè)趧?chuàng)建和使用B+樹(shù)索引的過(guò)程中需要注意的一些點(diǎn),后邊我們還會(huì)陸續(xù)介紹更多的優(yōu)化方法和注意事項(xiàng),敬請(qǐng)期待。本集內(nèi)容總結(jié)如下:

  • B+樹(shù)索引在空間和時(shí)間上都有代價(jià),所以沒(méi)事兒別瞎建索引。
  • B+樹(shù)索引適用于下邊這些情況:
    • 全值匹配
    • 匹配左邊的列
    • 匹配范圍值
    • 精確匹配某一列并范圍匹配另外一列
    • 用于排序
    • 用于分組
  • 在使用索引時(shí)需要注意下邊這些事項(xiàng):
    • 只為用于搜索、排序或分組的列創(chuàng)建索引
    • 為列的基數(shù)大的列創(chuàng)建索引
    • 索引列的類(lèi)型盡量小
    • 可以只對(duì)字符串值的前綴建立索引
    • 只有索引列在比較表達(dá)式中單獨(dú)出現(xiàn)才可以適用索引
    • 為了盡可能少的讓聚簇索引發(fā)生頁(yè)面分裂和記錄移位的情況,建議讓主鍵擁有AUTO_INCREMENT屬性。
    • 定位并刪除表中的重復(fù)和冗余索引
    • 盡量使用覆蓋索引進(jìn)行查詢,避免回表帶來(lái)的性能損耗。
  • 總結(jié)

    以上是生活随笔為你收集整理的Mysql原理篇之索引不懂不要瞎用---04的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    日韩试看 | 国产一区在线免费观看 | 欧美天堂影院 | 国内精品久久久久国产 | 国产精品久久久久久久妇 | 亚洲精品玖玖玖av在线看 | 欧美另类美少妇69xxxx | 久草影视在线观看 | 国产高清免费观看 | 色吊丝在线永久观看最新版本 | 免费十分钟 | 久草线| 一二三区视频在线 | 五月婷婷在线视频观看 | 久久成人18免费网站 | 日本黄色免费在线观看 | 天天色 天天 | 久久超碰网| 国精产品满18岁在线 | av免费成人 | 亚洲国产高清在线观看视频 | 中文字幕在线高清 | 伊人久久五月天 | 麻豆视频免费入口 | 香蕉视频一级 | 日韩免费看 | 日韩欧美国产视频 | 91福利试看| 欧洲精品久久久久毛片完整版 | 午夜精品久久久久久久99 | 就要色综合 | 国产黄在线看 | 玖玖视频国产 | 久久久国产精品网站 | www.成人sex| 日韩在线观看你懂得 | 夜夜躁狠狠躁 | 欧美整片sss | 五月婷婷丁香六月 | 国产精品久久久影视 | 亚洲精品白浆高清久久久久久 | 婷婷成人在线 | 国产精品久久久久aaaa | 久草在线一免费新视频 | 日日爽天天爽 | 久久久免费看片 | 三级黄在线 | 婷婷综合 | 免费观看成年人视频 | 婷婷久久综合网 | 久草在线免费看视频 | 在线播放 一区 | 国产精品久久久久久影院 | 国产黄色片久久 | 国产伦理一区二区三区 | 久久免费视频播放 | 亚洲成av | 最新午夜 | 久一在线| 一区二区三区在线免费播放 | 久久久久久久国产精品影院 | 午夜久久久精品 | av在线免费在线观看 | 在线免费亚洲 | 欧美性生交大片免网 | 免费毛片一区二区三区久久久 | 日韩精品不卡在线观看 | 高清av网| 中文在线字幕免 | 欧美精品黑人性xxxx | 在线一二三四区 | 亚洲禁18久人片 | 国产精品久久久久久一区二区三区 | 狠狠色丁香久久婷婷综 | 午夜三级大片 | 天天射天天色天天干 | 亚洲国内精品在线 | 欧美日韩国产综合一区二区 | 超碰电影在线观看 | 久久免费成人 | 99久久er热在这里只有精品66 | 一区二区三区电影在线播 | av字幕在线 | 99久久99久久精品免费 | 久久国产精品99久久久久久进口 | 久99久在线 | 高清国产在线一区 | 日韩av一区二区三区在线观看 | 欧美-第1页-屁屁影院 | 韩日电影在线免费看 | 麻豆精品91| 在线亚洲观看 | 久久国产精品久久精品 | 人人爽影院| 国产精品久久久久久久久久久久 | 国内精品久久久久影院一蜜桃 | 久久久久久久久影视 | 日本爱爱片 | 国产麻豆精品在线观看 | 久久99精品国产麻豆宅宅 | 欧美 日韩 国产 中文字幕 | 中文字幕综合在线 | 91人人在线| 三上悠亚一区二区在线观看 | 久久久久一区二区三区四区 | 国产无限资源在线观看 | 亚洲综合射| 国产精品免费视频网站 | 国产在线播放一区 | 99在线精品视频在线观看 | 国产一级二级在线播放 | www免费黄色| 91超在线 | 99精品一区 | 免费看片成年人 | 免费看一级黄色大全 | 日韩精品一区电影 | 成人免费看电影 | a在线播放 | 字幕网av | a在线免费观看视频 | 久久久色 | 欧美视频国产视频 | 国产免费一区二区三区最新6 | 激情综合色综合久久综合 | 日产乱码一二三区别在线 | 亚洲91在线| 日韩中文字幕免费看 | 91色亚洲| 日韩激情片在线观看 | 亚州中文av | 日日草视频 | 日本视频网 | 国产成人一区二区三区久久精品 | 在线影院av | 97精品在线观看 | 日韩免费b| 亚洲成人精品影院 | 久久精品国产美女 | 五月婷丁香 | 青青河边草手机免费 | 欧美精品一区二区在线观看 | 9999免费视频 | 国产一区免费在线 | 日韩三级在线观看 | 日韩激情视频在线观看 | av成人在线播放 | 在线观看av麻豆 | 中文字幕在线观看网站 | 日韩av电影免费观看 | 久草在线免费资源 | 五月婷婷开心中文字幕 | 91视频一8mav | 色婷婷综合久久久久中文字幕1 | 西西444www大胆高清图片 | 日韩国产在线观看 | 日本精品一区二区 | 天天添夜夜操 | 五月婷婷丁香网 | 免费观看的黄色 | 国产黄免费看 | 国产在线黄色 | 久久精品久久精品 | 久久久久久99精品 | 欧美精品三级 | 国产精品一区二区电影 | 亚洲精品久久在线 | 69精品视频 | 亚洲人精品午夜 | 夜夜夜| 黄色小说免费在线观看 | 免费视频三区 | 久草视频国产 | 香蕉影院在线观看 | 97手机电影网 | 色综合色综合色综合 | 中文字幕免费一区 | 色狠狠狠| 最近最新mv字幕免费观看 | 国模精品一区二区三区 | 亚洲在线视频网站 | 伊人黄| 欧洲一区二区在线观看 | 亚洲一区黄色 | 久久热首页 | 久久久国产99久久国产一 | 色.com| 在线视频中文字幕一区 | 久久久久久久影院 | 91看片淫黄大片一级在线观看 | 亚洲 中文 欧美 日韩vr 在线 | 一区精品在线 | 日韩一区正在播放 | 日本黄色免费电影网站 | 国产精品九九九九九 | 国产精品成人久久久 | 国产精品久久久久久久久久久久午夜 | 日韩在线观看免费 | 久久久国产精品电影 | 男女拍拍免费视频 | 日韩av电影网站在线观看 | 欧美日韩一区二区免费在线观看 | 日本中文乱码卡一卡二新区 | 国产分类视频 | 区一区二区三在线观看 | av软件在线观看 | 久久这里只有精品视频首页 | 国模精品一区二区三区 | 欧美激情操| 免费观看9x视频网站在线观看 | 久久免费99精品久久久久久 | 亚洲免费小视频 | 日韩久久精品一区二区三区 | 操操操com | 人人超在线公开视频 | 天天草天天色 | 色视频在线免费 | 欧美一级电影在线观看 | 亚洲免费av电影 | 五月色丁香 | 久草影视在线观看 | 色婷婷亚洲婷婷 | 久久黄色免费视频 | 黄色软件大全网站 | 日韩欧美91 | 免费日韩在线 | 麻豆 91 在线| 夜夜躁日日躁狠狠久久av | 久热国产视频 | 成人动漫精品一区二区 | 久草| 又黄又爽又无遮挡免费的网站 | 日日干天天爽 | 人人爽人人爱 | 91精品国产综合久久福利不卡 | 欧美一级黄色片 | 免费色av| 国产高清在线永久 | 成年人在线 | 天天激情在线 | 成人毛片在线观看视频 | 九九热re | 黄色日批网站 | 免费av试看 | 国产精品一区二区三区久久久 | 在线观看韩日电影免费 | 亚洲精品乱码久久久久久按摩 | 色悠悠久久综合 | 亚洲欧洲av | 欧美一级日韩免费不卡 | 中文字幕av最新 | 黄色软件在线看 | 特级西西444www大精品视频免费看 | 九九热只有这里有精品 | 五月天亚洲激情 | 欧美最猛性xxx| 久久这里只有精品久久 | 麻豆视频国产 | 激情伊人五月天久久综合 | 黄a在线观看 | 国产中文视 | www.狠狠色 | 久久综合婷婷综合 | 波多野结衣理论片 | 国产自在线观看 | 久久国产精品久久久 | 免费观看视频黄 | 日韩在线观看小视频 | 91精品欧美 | 日韩视频区 | 精品五月天 | 中文字幕视频网 | 在线免费观看国产视频 | 色婷婷免费视频 | 亚洲国产中文在线观看 | 丁香综合网 | 久久精品一二三区白丝高潮 | 日日夜夜网| 国产尤物在线视频 | 91麻豆网 | 欧美精品二区 | 国产精品一区二区久久久久 | 日韩中文在线电影 | 久草视频在线免费看 | 香蕉色综合 | 日韩欧美一区二区三区在线观看 | 91久久丝袜国产露脸动漫 | 中文字幕亚洲五码 | 狠狠网亚洲精品 | 97热久久免费频精品99 | 免费中午字幕无吗 | 91福利视频免费 | 就要干b| 欧美另类高潮 | 操天天操 | 激情综合中文娱乐网 | 日韩免费在线观看视频 | 日日干天天 | 91久久国产综合精品女同国语 | 在线观看视频一区二区三区 | 亚洲激情国产精品 | 特级a老妇做爰全过程 | 久久午夜网 | 国产黄在线免费观看 | 人成免费网站 | 在线观看久草 | 婷婷av色综合 | 毛片888| 又爽又黄又刺激的视频 | www.狠狠色.com| 国内精品二区 | 久久男人中文字幕资源站 | 日韩久久精品一区二区三区 | 福利网址在线观看 | 国产精品久久久久毛片大屁完整版 | 色偷偷888欧美精品久久久 | 欧美日韩首页 | 免费看污的网站 | a在线观看免费视频 | 亚洲涩涩涩涩涩涩 | 婷婷丁香六月天 | 天天躁天天操 | 国产美女在线精品免费观看 | 久久大香线蕉app | 综合色在线观看 | 色婷婷精品大在线视频 | 中文字幕精品在线 | 国产亚洲永久域名 | 中文字幕在线日本 | www.99久久.com | 久久99热久久99精品 | 国产国产人免费人成免费视频 | 国产网站av | 久久伊人国产精品 | 日日操夜夜操狠狠操 | 欧美做受高潮电影o | 手机看片国产 | 久久女同性恋中文字幕 | 日韩网站一区二区 | 国产精品一区二区三区观看 | 一区二区三区精品在线视频 | 亚洲国产精品久久久久婷婷884 | 久久久国产精品人人片99精片欧美一 | 婷婷久久五月天 | 久久久久高清 | 欧美男男tv网站 | 欧美黑人性猛交 | 蜜桃久久久| 国产精品一区二区三区在线免费观看 | 久久久久北条麻妃免费看 | 免费观看国产视频 | 国产免费三级在线观看 | 久久久影视 | 久久xx视频 | 精品免费观看 | 操操操日日 | 午夜国产一区 | 国产一区二区免费看 | 国产一区电影在线观看 | 国产精品手机看片 | 中文字幕第一页在线vr | 欧美大片mv免费 | 亚洲一区二区三区四区在线视频 | 1024久久 | 精品高清视频 | 特级片免费看 | 九九热在线免费观看 | 色视频网页 | 久久免费视频一区 | 天天色天天射天天干 | 国内精品视频在线 | 国产精品九九久久99视频 | 久99视频 | 黄色软件在线看 | 最近中文字幕完整视频高清1 | 操操爽| 国产黄色理论片 | 超碰人人草人人 | 天天操夜夜操夜夜操 | 麻豆高清免费国产一区 | 天天插狠狠插 | 欧美91精品国产自产 | 国产美女在线精品免费观看 | 免费a v在线 | av免费在线观看网站 | 激情综合色综合久久 | 精产嫩模国品一二三区 | 91亚洲精品在线 | 国产成人久久77777精品 | 亚洲传媒在线 | 中文字幕视频网站 | 日韩和的一区二在线 | 91完整视频| 精品国产乱码久久久久久1区二区 | 永久黄网站色视频免费观看w | 欧美一区免费观看 | 国产日本在线播放 | 欧美日韩午夜 | 九热精品| 亚州天堂 | 欧美成人黄色片 | 久久99日韩| www.天天干 | 日本黄色免费电影网站 | 久久欧美精品 | 99色在线播放 | www.午夜色.com | 丁香六月av | 天堂入口网站 | 日韩国产精品毛片 | 国产在线 一区二区三区 | 中文字幕在线观看播放 | 999成人| 免费三级大片 | 久久综合99| 丁香亚洲 | 激情小说 五月 | 狠狠躁日日躁狂躁夜夜躁 | 久久大香线蕉app | 中文字幕在线久一本久 | 国产精品欧美久久久久天天影视 | 国产欧美在线一区二区三区 | 国产视频欧美视频 | 亚洲资源在线网 | 99久久爱| 亚洲精品久久久久久久蜜桃 | 精品视频在线免费 | 天天玩天天操天天射 | 91在线蜜桃臀 | 国内视频 | 91在线影视 | 中文字幕在线播放一区 | 精品一区二区在线播放 | 婷婷色亚洲| 999电影免费在线观看2020 | 色视频网站在线观看一=区 a视频免费在线观看 | 91精品国产91久久久久福利 | 激情在线免费视频 | 国产视频在线看 | 超碰在线公开 | 久久99久久99精品 | 一区二区不卡视频在线观看 | 久久久久久国产精品 | 国产字幕在线播放 | 国产成人精品一区二区三区网站观看 | 中文字幕 91 | 色wwwww| 欧美男同网站 | 久久国产精彩视频 | 欧美一级视频免费 | 国产精品aⅴ | 欧美性生爱 | 久久久久福利视频 | 欧美日韩一区久久 | 成人av在线播放网站 | 中文字幕 婷婷 | 国产精品久久99综合免费观看尤物 | 国产精品999久久久 久产久精国产品 | 成人网页在线免费观看 | 亚洲精品视频免费在线观看 | 九九99| 伊甸园av在线 | 欧美精品乱码久久久久久 | 国产永久网站 | 日本中文字幕观看 | 人人爽人人爽人人 | 久久精品久久综合 | av在线免费播放网站 | 亚洲精品美女久久久久 | 久99久在线视频 | 日韩二区在线播放 | 久久精品视 | 国产精品视频区 | 91精品日韩 | 91激情在线视频 | 亚洲黄色在线免费观看 | 九九免费观看视频 | 欧美人zozo | 国产精品国内免费一区二区三区 | 91综合色 | av中文字幕免费在线观看 | 国产精品久久久久av福利动漫 | 国产精品一区二区久久久久 | 亚洲综合精品在线 | 日日操狠狠干 | 又湿又紧又大又爽a视频国产 | 免费亚洲电影 | 亚洲美女久久 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 亚洲砖区区免费 | 国产乱对白刺激视频不卡 | 色婷婷狠狠18 | 国产午夜视频在线观看 | 日韩av福利在线 | 少妇bbbb揉bbbb日本 | 深夜免费福利视频 | 色婷婷国产精品一区在线观看 | 亚洲国产精品一区二区久久,亚洲午夜 | 玖草在线观看 | 欧美精品一级视频 | 亚洲精欧美一区二区精品 | 日韩久久午夜一级啪啪 | 精品国产电影 | 超碰激情在线 | 91在线91拍拍在线91 | 国产麻豆精品久久 | 黄色特级一级片 | 毛片精品免费在线观看 | 亚洲涩综合 | 97成人啪啪网 | 日韩国产精品久久 | 亚洲精品乱码久久久久久9色 | 免费观看一级成人毛片 | 天天综合入口 | 久久国产成人午夜av影院宅 | 天天射网站 | 午夜精品视频福利 | 99精品欧美一区二区三区 | 免费看黄视频 | 色综合天天在线 | 五月婷影院| 激情av资源| 黄色网大全 | 久久久亚洲麻豆日韩精品一区三区 | 中文字幕频道 | 国产精品欧美 | 97精品欧美91久久久久久 | 国产精品久久久久aaaa九色 | 99欧美| 一区二区三区四区影院 | a天堂最新版中文在线地址 久久99久久精品国产 | 又黄又爽又色无遮挡免费 | 国产做aⅴ在线视频播放 | 99精品免费久久久久久久久 | 国产精品资源在线观看 | 五月婷婷视频在线 | 免费日韩av电影 | 久久99欧美 | 亚洲精品白浆高清久久久久久 | 正在播放国产91 | 成人aⅴ视频 | 精品国产伦一区二区三区观看方式 | 国产人成看黄久久久久久久久 | 免费看av在线| 99视频精品 | 99在线免费观看视频 | 亚洲高清av在线 | 欧美怡红院 | 最近日本字幕mv免费观看在线 | 五月天综合激情网 | 成人av免费在线观看 | 九九热精品国产 | 丁香午夜 | 91在线91拍拍在线91 | 久久久久久久久久免费 | 亚洲国产一区二区精品专区 | 成人在线免费观看网站 | 欧美成人精品欧美一级乱黄 | 欧美性色综合网站 | 国产九九热视频 | 91色国产在线 | 91亚洲激情 | 99久久毛片 | 一区二区欧美在线观看 | 天天爽天天爽夜夜爽 | 国产欧美精品一区二区三区 | 日本女人在线观看 | 国产精品2区 | 99精品久久久久久久 | 九九热免费在线视频 | 超碰免费av| 欧美日韩亚洲国产一区 | 99爱精品视频 | 最新国产一区二区三区 | 99国产精品 | 中文字幕在线影院 | 91亚色视频在线观看 | 精品综合久久 | 国产视频在线播放 | 免费看黄色91 | 天天色 天天| 国产成本人视频在线观看 | 综合网天天 | 在线播放国产一区二区三区 | 久久久久久久国产精品影院 | 免费看黄在线看 | 午夜视频播放 | 99视频免费 | 99久久999久久久精玫瑰 | 国产高清精品在线 | 国内久久久久久 | 国产一区二区不卡视频 | 亚洲高清精品在线 | 99视频在线观看视频 | 三日本三级少妇三级99 | 又黄又爽又无遮挡免费的网站 | 日本中文字幕在线观看 | 特级a老妇做爰全过程 | 日日草天天干 | 奇米先锋| 制服丝袜在线91 | 日韩色高清 | 久久女同性恋中文字幕 | 久久综合给合久久狠狠色 | 91精品国自产拍天天拍 | 日韩精品久久久久久中文字幕8 | 亚洲激情久久 | 日韩欧美在线不卡 | 二区三区在线视频 | 国产一区国产精品 | www.狠狠插.com | 久久精品超碰 | 日韩av三区| 免费在线激情视频 | 日韩av中文在线 | 日韩av三区 | 欧美 高跟鞋交 xxxxhd | 在线看小早川怜子av | 九九免费在线观看 | 欧美国产日韩激情 | 亚洲一区美女视频在线观看免费 | 日本中文字幕一二区观 | 久久99热精品这里久久精品 | 黄色三级免费片 | 欧美精品久久天天躁 | 97香蕉久久国产在线观看 | 婷婷久久婷婷 | 精品国自产在线观看 | 亚洲欧洲xxxx | 美女视频黄在线 | 日韩精品专区 | 天天在线视频色 | 午夜精品一区二区三区在线视频 | 色丁香婷婷 | 国产成人精品国内自产拍免费看 | 日韩欧美xxxx | 人人澡人人添人人爽一区二区 | www.少妇| 成人中文字幕av | 国产亚洲精品久久久久秋 | 一区二区三区在线免费播放 | 黄色一级大片在线免费看产 | 亚洲激情视频 | 久久精品在线免费观看 | 色婷婷中文 | 日韩国产欧美在线视频 | 在线天堂亚洲 | 国产视频一区精品 | 精品一二 | 日韩高清片 | 欧美一区二区日韩一区二区 | 亚洲国产97在线精品一区 | 精品亚洲免费 | 日韩a级黄色片 | 国产亚洲视频在线 | 中文字幕久久亚洲 | 欧美男同网站 | 国产这里只有精品 | 国产亚洲精品久久久久久无几年桃 | 日本中文字幕系列 | 日韩欧美在线视频一区二区三区 | 日韩精品一区二区三区电影 | 亚洲精品456在线播放 | 免费手机黄色网址 | 欧美一级性 | 一级黄色大片在线观看 | 成人在线视频论坛 | 91入口在线观看 | 欧美视频99 | 国产98色在线 | 日韩 | 日韩欧美电影 | 五月激情久久 | 日本一区二区不卡高清 | 99免费看片 | 天天操天天射天天添 | 天天干,夜夜操 | 九九视频免费在线观看 | 综合色站 | 99视频精品在线 | 国产精品不卡在线 | 国产精品美女免费 | caobi视频| 国产在线综合视频 | 96av麻豆蜜桃一区二区 | 欧美日韩在线视频免费 | 狠狠的日日 | a视频免费在线观看 | 久久国产欧美日韩精品 | 国产精品激情偷乱一区二区∴ | 亚洲最新av网站 | 国产国语在线 | 久草新在线 | 国产一区网址 | 中文久久精品 | 国产精品视频app | 久久精品一二三区白丝高潮 | 91中文在线观看 | 91网址在线看 | 中日韩三级视频 | av福利网址导航 | 亚洲精品中文字幕视频 | 亚洲精品日韩一区二区电影 | 国产一级片在线播放 | 97在线免费视频观看 | 国产我不卡| 国内精品免费 | 国产成人精品一区二区三区免费 | av一区在线 | 久久不射电影院 | 91视频高清免费 | 色噜噜色噜噜 | 国产男男gay做爰 | 日韩在线视频一区二区三区 | 国产精品专区在线观看 | 国产精品成人品 | 久久精品久久精品久久精品 | 97超碰国产精品 | 欧美淫aaa免费观看 日韩激情免费视频 | 美国av片在线观看 | 色国产精品一区在线观看 | 97人人爽 | 色视频网页 | 国产女人免费看a级丨片 | 中文字幕乱在线伦视频中文字幕乱码在线 | 久久网址| 欧美日韩亚洲第一 | 中文av字幕在线观看 | 91自拍视频在线观看 | 狠狠狠色丁香综合久久天下网 | 日韩二三区| 国产亚洲精品无 | 在线观看一区二区视频 | 日韩精品一区二区免费视频 | 天天干夜夜夜操天 | 久久另类小说 | 四虎在线免费观看 | 精品久久综合 | 伊人色播 | 中文字幕精品www乱入免费视频 | 天天爽天天射 | 日日夜日日干 | 黄色av网站在线免费观看 | 免费电影一区二区三区 | 亚洲精品男人天堂 | 日韩欧美在线高清 | 国外调教视频网站 | 97超级碰碰碰碰久久久久 | 99久久久国产精品美女 | 国产黄色电影 | 在线国产福利 | www.久久视频 | 久久99国产综合精品 | 中文字幕电影网 | 亚洲人人精品 | 美女视频国产 | 中文字幕一区二区三区在线视频 | 国产 欧美 日产久久 | 久久1电影院 | 日韩在线高清视频 | 色妞久久福利网 | 精品自拍网| 国产精品久久久 | 欧美日韩国产精品一区二区亚洲 | 久久一区91| 久久男人免费视频 | 干干干操操操 | 国产精品系列在线观看 | av在线小说 | 黄色小网站在线 | 中文在线a天堂 | 992tv在线| 日韩精品观看 | 深爱婷婷网 | 国产一区私人高清影院 | 国产资源网 | 97在线免费观看 | 美女免费网站 | 精品亚洲视频在线 | 精品国产aⅴ麻豆 | 国产一级免费播放 | 久久久久久麻豆 | 日本三级不卡视频 | 成x99人av在线www | 美女在线观看网站 | 国产精品不卡一区 | 日韩在线视频播放 | 91精品久久久久久久久 | 国产美女视频免费观看的网站 | av网站在线免费观看 | 国产精品久久久久aaaa九色 | 亚洲精品乱码久久久久久 | 少妇bbw搡bbbb搡bbb | 午夜精品久久久久久久久久久 | 一区二区电影网 | 日韩爱爱片 | 一区中文字幕电影 | 天天干天天干天天 | 在线观看免费版高清版 | 视频一区在线免费观看 | 91麻豆精品国产自产在线游戏 | 黄色一级片视频 | 久草在线观看资源 | 亚洲日韩中文字幕 | 国产91大片 | 日韩在线观看一区 | 香蕉影视 | 亚洲高清精品在线 | 亚洲一区网 | 久久久久久久久久久综合 | 免费美女av | 欧美一级激情 | 99国产精品久久久久久久久久 | av黄色免费网站 | 日韩欧美91 | 国内精品久久久久久 | 久久久久一区二区三区 | 国产精品视频永久免费播放 | 91九色成人 | 亚洲激情在线 | 午夜视频在线网站 | 久久国产精品一区二区三区四区 | 免费视频在线观看网站 | 深夜福利视频一区二区 | 精品国产精品国产偷麻豆 | 国产美女精品 | 欧洲一区二区在线观看 | 中文字幕一区二区三区乱码在线 | www免费黄色| 成人av一区二区兰花在线播放 | 天天弄天天干 | 日韩精品一区二区三区第95 | 国产精品色视频 | 91福利专区 | 中文字幕91在线 | 国产精品久久艹 | 最新高清无码专区 | 91超碰免费在线 | 免费看一级特黄a大片 | 欧洲色综合 | 91久久久久久久一区二区 | 97碰碰视频 | 99视频在线免费 | 六月婷操 | 伊人丁香 | 91精品久久久久久综合乱菊 | 天天做天天爱天天爽综合网 | 亚洲人人网 | 国产精品免费视频网站 | 久久午夜影视 | 999视频在线观看 | 久久黄色片子 | 成人超碰在线 | 亚洲国产欧美一区二区三区丁香婷 | 国产精品精品久久久久久 | www.香蕉 | 91成人天堂久久成人 | 国产裸体bbb视频 | 在线观看911视频 | 日本aa在线| 国产精品久久久久久婷婷天堂 | 热久久这里只有精品 | 韩国一区二区三区视频 | 成人在线电影观看 | 亚洲区视频在线 | 亚洲国产精品500在线观看 | 国产精品区一区 | 亚洲成色777777在线观看影院 | 成人免费在线电影 | 国产精品综合av一区二区国产馆 | 日韩一级黄色大片 | 国产精品久久视频 | 亚洲一二三久久 | 国产一区二区在线播放视频 | 国产精品免费看 | 日韩欧美在线不卡 | 欧美91精品国产自产 | 欧美日韩精品免费观看视频 | 麻豆视频在线免费观看 | 亚洲成人麻豆 | 天天干人人 | 免费网址你懂的 | 99久免费精品视频在线观看 | 麻花豆传媒一二三产区 | 久久综合久久综合这里只有精品 | 久久ww| 亚洲天堂在线观看完整版 | 国产日韩中文在线 | 五月天久久久 | av福利在线免费观看 | 香蕉精品在线观看 | 人人搞人人干 | 人人干网站 | 日韩免费在线播放 | 久久久久亚洲精品男人的天堂 | 亚洲欧美日韩一区二区三区在线观看 | 99热这里只有精品在线观看 | 亚洲成人资源 | 99精品在线直播 | 国产原创在线 | 欧美精品久久久久久久久老牛影院 | 国产精品久久久久久久久费观看 | 亚洲国产午夜精品 | 99在线观看精品 | 很黄很黄的网站免费的 | 色婷av| 深夜福利视频一区二区 | 午夜影视剧场 | 天天综合天天综合 | 黄网站免费久久 | 在线亚洲欧美视频 | 国产精品美乳一区二区免费 | 91麻豆精品久久久久久 | 天天干天天射天天爽 | 国产精品原创视频 | 91香蕉视频黄色 | 丁香色综合 | 日日夜夜天天人人 | 久久99国产精品久久 | 天天添夜夜操 | 97视频在线观看播放 | 久久久久久久久国产 | 91亚洲欧美激情 | 久草视频99 | 欧美性生活一级片 | 久久99久久久久久 | 黄色一级大片在线免费看国产一 | 亚洲精品456在线播放乱码 | 成人免费观看在线视频 | 深爱五月网 | 国产成人精品一区二三区 | 97人人超碰在线 | 99久久久久久久久 | 免费看国产黄色 | 日韩在线观看精品 | 97精品国产97久久久久久 | 亚洲综合视频网 | 国产精品麻豆三级一区视频 | 久久综合加勒比 | 在线观看成人国产 | 中文字幕黄网 | 亚洲免费av一区二区 | 超碰成人免费电影 | 久久精品精品电影网 | 国产91勾搭技师精品 | 久久撸在线视频 | 国产一区二区不卡视频 | 人人草人人做 | av高清网站在线观看 | 久色婷婷 | 欧美一级裸体视频 | 久久久精品亚洲 | 99操视频| 国产成人一区三区 | 狠狠色丁香九九婷婷综合五月 | 久久在线视频在线 | 天天拍天天操 | 成人午夜在线电影 | 日韩三级.com | 久草在线免费在线观看 | 亚洲精品在线观看网站 | 国产福利一区二区三区在线观看 | 国外调教视频网站 | 亚洲一区二区视频在线 | 欧美精品免费在线 | 丁香婷婷激情国产高清秒播 | 久久久一本精品99久久精品 | 91色亚洲 | 97日日碰人人模人人澡分享吧 | 婷婷婷国产在线视频 | 亚洲婷婷综合色高清在线 | 欧洲亚洲女同hd | avcom在线| 婷婷色五 | 国产亚洲一级高清 | 亚洲2019精品 | 在线观看国产永久免费视频 | 久99久久| 国产第一页在线观看 | 久草在线资源网 | 精品久久久久一区二区国产 | 黄色av影视 | 国产高清视频在线播放一区 | 在线看片中文字幕 | 日本久久精品 | 亚洲,国产成人av | 欧美日韩一区二区视频在线观看 | 色诱亚洲精品久久久久久 | 婷婷丁香激情 | 最近中文字幕视频完整版 | 97精品久久人人爽人人爽 | 日韩视频专区 | 久久免费黄色网址 | 中文字幕在线观看一区二区 | 久久久国产精品电影 | 亚洲综合成人av | 91久久偷偷做嫩草影院 | 999久久a精品合区久久久 | 日日操网 |