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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Mysql B+树索引的使用

發布時間:2023/12/20 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mysql B+树索引的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文地址:https://amos-x.com/index.php/amos/archives/mysql-btree-use/

正文

上一篇,說了B+樹索引的原理和其為什么能提高查詢效率,那么有個索引時不是就可以為所欲為呢,答案顯然并不是,下面就詳細介紹一下,索引的使用和限制,這雖然不常在面試中出現,但能幫助我們更好的設計數據庫Model結構和使用數據庫查詢語句,以提升系統性能。

我覺得是必須知道的重要知識,很有其必要。

正文

我們前邊詳細、詳細又詳細的嘮叨了InnoDB存儲引擎的B+樹索引,我們必須熟悉下邊這些結論:

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

如果你讀上邊的幾點結論有些任何一點點疑惑的話,那下邊的內容不適合你,回過頭先去看前邊的內容去。

索引的代價

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

  • 空間上的代價這個是顯而易見的,每建立一個索引都要為它建立一棵B+樹,每一棵B+樹的每一個節點都是一個數據頁,一個頁默認會占用16KB的存儲空間,一棵很大的B+樹由許多數據頁組成,那可是很大的一片存儲空間呢。
  • 時間上的代價每次對表中的數據進行增、刪、改操作時,都需要去修改各個B+樹索引。而且我們講過,B+樹每層節點都是按照索引列的值從小到大的順序排序而組成了雙向鏈表。不論是葉子節點中的記錄,還是內節點中的記錄(也就是不論是用戶記錄還是目錄項記錄)都是按照索引列的值從小到大的順序而形成了一個單向鏈表。而增、刪、改操作可能會對節點和記錄的排序造成破壞,所以存儲引擎需要額外的時間進行一些記錄移位,頁面分裂、頁面回收啥的操作來維護好節點和記錄的排序。如果我們建了許多索引,每個索引對應的B+樹都要進行相關的維護操作,這還能不給性能拖后腿么?

所以說,一個表上索引建的越多,就會占用越多的存儲空間,在增刪改記錄的時候性能就越差。為了能建立又好又少的索引,我們先得學學這些索引在哪些條件下起作用的。

B+樹索引適用的條件

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

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) );

對于這個person_info表我們需要注意兩點:

  • 表中的主鍵是id列,它存儲一個自動遞增的整數。所以InnoDB存儲引擎會自動為id列建立聚簇索引。
  • 我們額外定義了一個二級索引idx_name_birthday_phone_number,它是由3個列組成的聯合索引。所以在這個索引對應的B+樹的葉子節點處存儲的用戶記錄只保留name、birthday、phone_number這三個列的值以及主鍵id的值,并不會保存country列的值。

從這兩點注意中我們可以再次看到,一個表中有多少索引就會建立多少棵B+樹,person_info表會為聚簇索引和idx_name_birthday_phone_number索引建立2棵B+樹。下邊我們畫一下索引idx_name_birthday_phone_number的示意圖,不過既然我們已經掌握了InnoDB的B+樹索引原理,那我們在畫圖的時候為了讓圖更加清晰,所以在省略一些不必要的部分,比如記錄的額外信息,各頁面的頁號等等,其中內節點中目錄項記錄的頁號信息我們用箭頭來代替,在記錄結構中只保留name、birthday、phone_number、id這四個列的真實數據值,所以示意圖就長這樣:

為了方便大家理解,我們特意標明了哪些是內節點,哪些是葉子節點。再次強調一下,內節點中存儲的是目錄項記錄,葉子節點中存儲的是用戶記錄(由于不是聚簇索引,所以用戶記錄是不完整的,缺少country列的值)。從圖中可以看出,這個idx_name_birthday_phone_number索引對應的B+樹中頁面和記錄的排序方式就是這樣的:

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

這個排序方式十分、特別、非常、巨、very very very重要,因為只要頁面和記錄是排好序的,我們就可以通過二分法來快速定位查找。下邊的內容都仰仗這個圖了,大家對照著圖理解。

全值匹配

如果我們的搜索條件中的列和索引列一致的話,這種情況就稱為全值匹配,比方說下邊這個查找語句:

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

我們建立的idx_name_birthday_phone_number索引包含的3個列在這個查詢語句中都展現出來了。大家可以想象一下這個查詢過程:

  • 因為B+樹的數據頁和記錄先是按照name列的值進行排序的,所以先可以很快定位name列的值是Ashburn的記錄位置。
  • 在name列相同的記錄里又是按照birthday列的值進行排序的,所以在name列的值是Ashburn的記錄里又可以快速定位birthday列的值是'1990-09-27'的記錄。
  • 如果很不幸,name和birthday列的值都是相同的,那記錄是按照phone_number列的值排序的,所以聯合索引中的三個列都可能被用到。

有的同學也許有個疑問,WHERE子句中的幾個搜索條件的順序對查詢結果有啥影響么?也就是說如果我們調換name、birthday、phone_number這幾個搜索列的順序對查詢的執行過程有影響么?比方說寫成下邊這樣:

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

答案是:沒影響哈。MySQL有一個叫查詢優化器的東東,會分析這些搜索條件并且按照可以使用的索引中列的順序來決定先使用哪個搜索條件,后使用哪個搜索條件。我們后邊兒會有專門的章節來介紹查詢優化器,敬請期待。

匹配左邊的列

其實在我們的搜索語句中也可以不用包含全部聯合索引中的列,只包含左邊的就行,比方說下邊的查詢語句:

SELECT * FROM person_info WHERE name = 'Ashburn';

或者包含多個左邊的列也行:

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

那為什么搜索條件中必須出現左邊的列才可以使用到這個B+樹索引呢?比如下邊的語句就用不到這個B+樹索引么?

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

是的,的確用不到,因為B+樹的數據頁和記錄先是按照name列的值排序的,在name列的值相同的情況下才使用birthday列進行排序,也就是說name列的值不同的記錄中birthday的值可能是無序的。而現在你跳過name列直接根據birthday的值去查找,臣妾做不到呀~ 那如果我就想在只使用birthday的值去通過B+樹索引進行查找咋辦呢?這好辦,你再對birthday列建一個B+樹索引就行了,創建索引的語法不用我嘮叨了吧。

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

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

這樣只能用到name列的索引,birthday和phone_number的索引就用不上了,因為name值相同的記錄先按照birthday的值進行排序,birthday值相同的記錄才按照phone_number值進行排序。

匹配列前綴

我們前邊說過為某個列建立索引的意思其實就是在對應的B+樹的記錄中使用該列的值進行排序,比方說person_info表上建立的聯合索引idx_name_birthday_phone_number會先用name列的值進行排序,所以這個聯合索引對應的B+樹中的記錄的name列的排列就是這樣的:

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

字符串排序的本質就是比較哪個字符串大一點兒,哪個字符串小一點,比較字符串大小就用到了該列的字符集和比較規則,這個我們前邊兒嘮叨過,就不多嘮叨了。這里需要注意的是,一般的比較規則都是逐個比較字符的大小,也就是說我們比較兩個字符串的大小的過程其實是這樣的:

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

所以一個排好序的字符串列其實有這樣的特點:

  • 先按照字符串的第一個字符進行排序。
  • 如果第一個字符相同再按照第二個字符進行排序。
  • 如果第二個字符相同再按照第三個字符進行排序,依此類推。

也就是說這些字符串的前n個字符,也就是前綴都是排好序的,所以對于字符串類型的索引列來說,我們只匹配它的前綴也是可以快速定位記錄的,比方說我們想查詢名字以'As'開頭的記錄,那就可以這么寫查詢語句:

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

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

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

MySQL就無法快速定位記錄位置了,因為字符串中間有'As'的字符串并沒有排好序,所以只能全表掃描了。有時候我們有一些匹配某些字符串后綴的需求,比方說某個表有一個url列,該列中存儲了許多url:

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

假設已經對該url列創建了索引,如果我們想查詢以com為后綴的網址的話可以這樣寫查詢條件:WHERE url LIKE '%com',但是這樣的話無法使用該url列的索引。為了在查詢時用到這個索引而不至于全表掃描,我們可以把后綴查詢改寫成前綴查詢,不過我們就得把表中的數據全部逆序存儲一下,也就是說我們可以這樣保存url列中的數據:

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

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

匹配范圍值

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

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

由于B+樹中的數據頁和記錄是先按name列排序的,所以我們上邊的查詢過程其實是這樣的:

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

不過在使用聯合進行范圍查找的時候需要注意,如果對多個列同時進行范圍查找的話,只有對索引最左邊的那個列進行范圍查找的時候才能用到B+樹索引,比方說這樣:

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

上邊這個查詢可以分成兩個部分:

  • 通過條件name > 'Asa' AND name < 'Barlow'?來對name進行范圍,查找的結果可能有多條name值不同的記錄,
  • 對這些name值不同的記錄繼續通過birthday > '1980-01-01'條件繼續過濾。
  • 這樣子對于聯合索引idx_name_birthday_phone_number來說,只能用到name列的部分,而用不到birthday列的部分,因為只有name值相同的情況下才能用birthday列的值進行排序,而這個查詢中通過name進行范圍查找的記錄中可能并不是按照birthday列進行排序的,所以在搜索條件中繼續以birthday列進行查找時是用不到這個B+樹索引的。

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

    對于同一個聯合索引來說,雖然對多個列都進行范圍查找時只能用到最左邊那個索引列,但是如果左邊的列是精確查找,則右邊的列可以進行范圍查找,比方說這樣:

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

    這個查詢的條件可以分為3個部分:

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

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

    用于排序

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

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

    這個查詢的結果集需要先按照name值排序,如果記錄的name值相同,則需要按照birthday來排序,如果birthday的值相同,則需要按照phone_number排序。大家可以回過頭去看我們建立的idx_name_birthday_phone_number索引的示意圖,因為這個B+樹索引本身就是按照上述規則排好序的,所以直接從索引中提取數據,然后進行回表操作取出該索引中不包含的列就好了。簡單吧?是的,索引就是這么牛逼。

    使用聯合索引進行排序注意事項

    對于聯合索引有個問題需要注意,ORDER BY的子句后邊的列的順序也必須按照索引列的順序給出,如果給出ORDER BY phone_number, birthday, name的順序,那也是用不了B+樹索引,這種顛倒順序就不能使用索引的原因我們上邊詳細說過了,這就不贅述了。

    同理,ORDER BY name、ORDER BY name, birthday這種匹配索引左邊的列的形式可以使用部分的B+樹索引。當聯合索引左邊列的值為常量,也可以使用后邊的列進行排序,比如這樣:

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

    這個查詢能使用聯合索引進行排序是因為name列的值相同的記錄是按照birthday,?phone_number排序的,說了好多遍了都。

    不可以使用索引進行排序的幾種情況

    ASC、DESC混用

    對于使用聯合索引進行排序的場景,我們要求各個排序列的排序順序是一致的,也就是要么各個列都是ASC規則排序,要么都是DESC規則排序。

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

    為啥會有這種奇葩規定呢?這個還得回頭想想這個idx_name_birthday_phone_number聯合索引中記錄的結構:

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

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

    • ORDER BY name, birthday LIMIT 10這種情況直接從索引的最左邊開始往右讀10行記錄就可以了。
    • ORDER BY name DESC, birthday DESC LIMIT 10,這種情況直接從索引的最右邊開始往左讀10行記錄就可以了。

    但是如果我們查詢的需求是先按照name列進行升序排列,再按照birthday列進行降序排列的話,比如說這樣的查詢語句:

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

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

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

    累不累?累!重點是這樣不能高效使用索引,而要采取更復雜的算法去從索引中取數據,設計MySQL的大叔覺得這樣還不如直接文件排序來的快,所以就規定使用聯合索引的各個排序列的排序順序必須是一致的。

    排序列包含非同一個索引的列

    有時候用來排序的多個列不是一個索引里的,這種情況也不能使用索引進行排序,比方說:

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

    name和country并不屬于一個聯合索引中的列,所以無法使用索引進行排序,至于為啥我就不想再嘮叨了,自己用前邊的理論自己捋一捋吧~

    排序列使用了復雜的表達式

    要想使用索引進行排序操作,必須保證索引列是以單獨列的形式出現,而不是修飾過的形式,比方說這樣:

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

    使用了UPPER函數修飾過的列就不是單獨的列啦,這樣就無法使用索引進行排序啦。

    用于分組

    有時候我們為了方便統計表中的一些信息,會把表中的記錄按照某些列進行分組。比如下邊這個分組查詢:

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

    這個查詢語句相當于做了3次分組操作:

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

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

    回表的代價

    上邊的討論對回表這個詞兒多是一帶而過,可能大家沒啥深刻的體會,下邊我們詳細嘮叨下。還是用idx_name_birthday_phone_number索引為例,看下邊這個查詢:

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

    在使用idx_name_birthday_phone_number索引進行查詢時大致可以分為這兩個步驟:

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

    • 會使用到兩個B+樹索引,一個二級索引,一個聚簇索引。
    • 訪問二級索引使用順序I/O,訪問聚簇索引使用隨機I/O。

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

    那什么時候采用全表掃描的方式,什么時候使用采用二級索引 + 回表的方式去執行查詢呢?這個就是傳說中的查詢優化器做的工作,查詢優化器會事先對表中的記錄計算一些統計數據,然后再利用這些統計數據根據查詢的條件來計算一下需要回表的記錄數,需要回表的記錄數越多,就越傾向于使用全表掃描,反之傾向于使用二級索引 + 回表的方式。當然優化器做的分析工作不僅僅是這么簡單,但是大致上是個這個過程。一般情況下,限制查詢獲取較少的記錄數會讓優化器更傾向于選擇使用二級索引 + 回表的方式進行查詢,因為回表的記錄越少,性能提升就越高,比方說上邊的查詢可以改寫成這樣:

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

    添加了LIMIT 10的查詢更容易讓優化器采用二級索引 + 回表的方式進行查詢。

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

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

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

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

    這樣需要回表的記錄特別少,優化器就會傾向于使用二級索引 + 回表的方式執行查詢。

    覆蓋索引

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

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

    因為我們只查詢name,?birthday,?phone_number這三個索引列的值,所以在通過idx_name_birthday_phone_number索引得到結果后就不必到聚簇索引中再查找記錄的剩余列,也就是country列的值了,這樣就省去了回表操作帶來的性能損耗。我們把這種只需要用到索引的查詢方式稱為索引覆蓋。排序操作也優先使用覆蓋索引的方式進行查詢,比方說這個查詢:

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

    雖然這個查詢中沒有LIMIT子句,但是采用了覆蓋索引,所以查詢優化器就會直接使用idx_name_birthday_phone_number索引進行排序而不需要回表操作了。

    當然,如果業務需要查詢出索引以外的列,那還是以保證業務需求為重。但是我們很不鼓勵用*號作為查詢列表,最好把我們需要查詢的列依次標明。

    如何挑選索引

    上邊我們以idx_name_birthday_phone_number索引為例對索引的適用條件進行了詳細的嘮叨,下邊看一下我們在建立索引時或者編寫查詢語句時就應該注意的一些事項。

    只為用于搜索、排序或分組的列創建索引

    也就是說,只為出現在WHERE子句中的列、連接子句中的連接列,或者出現在ORDER BY或GROUP BY子句中的列創建索引。而出現在查詢列表中的列就沒必要建立索引了:

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

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

    考慮列的基數

    列的基數指的是某一列中不重復數據的個數,比方說某個列包含值2, 5, 8, 2, 5, 8, 2, 5, 8,雖然有9條記錄,但該列的基數卻是3。也就是說,在記錄行數一定的情況下,列的基數越大,該列中的值越分散,列的基數越小,該列中的值越集中。這個列的基數指標非常重要,直接影響我們是否能有效的利用索引。假設某個列的基數為1,也就是所有記錄在該列中的值都一樣,那為該列建立索引是沒有用的,因為所有值都一樣就無法排序,無法進行快速查找了~ 而且如果某個建立了二級索引的列的重復值特別多,那么使用這個二級索引查出的記錄還可能要做回表操作,這樣性能損耗就更大了。所以結論就是:最好為那些列的基數大的列建立索引,為基數太小列的建立索引效果可能不好。

    索引列的類型盡量小

    我們在定義表結構的時候要顯式的指定列的類型,以整數類型為例,有TINYINT、MEDIUMINT、INT、BIGINT這么幾種,它們占用的存儲空間依次遞增,我們這里所說的類型大小指的就是該類型表示的數據范圍的大小。能表示的整數范圍當然也是依次遞增,如果我們想要對某個整數列建立索引的話,在表示的整數范圍允許的情況下,盡量讓索引列使用較小的類型,比如我們能使用INT就不要使用BIGINT,能使用MEDIUMINT就不要使用INT~ 這是因為:

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

    這個建議對于表的主鍵來說更加適用,因為不僅是聚簇索引中會存儲主鍵值,其他所有的二級索引的節點處都會存儲一份記錄的主鍵值,如果主鍵適用更小的數據類型,也就意味著節省更多的存儲空間和更高效的I/O。

    索引字符串值的前綴

    我們知道一個字符串其實是由若干個字符組成,如果我們在MySQL中使用utf8字符集去存儲字符串的話,編碼一個字符需要占用1~3個字節。假設我們的字符串很長,那存儲一個字符串就需要占用很大的存儲空間。在我們需要為這個字符串列建立索引時,那就意味著在對應的B+樹中有這么兩個問題:

    • B+樹索引中的記錄需要把該列的完整字符串存儲起來,而且字符串越長,在索引中占用的存儲空間越大。
    • 如果B+樹索引中索引列存儲的字符串很長,那在做字符串比較時會占用更多的時間。

    我們前邊兒說過索引列的字符串前綴其實也是排好序的,所以索引的設計者提出了個方案 —?只對字符串的前幾個字符進行索引也就是說在二級索引的記錄中只保留字符串前幾個字符。這樣在查找記錄時雖然不能精確的定位到記錄的位置,但是能定位到相應前綴所在的位置,然后根據前綴相同的記錄的主鍵值回表查詢完整的字符串值,再對比就好了。這樣只在B+樹中存儲字符串的前幾個字符的編碼,既節約空間,又減少了字符串的比較時間,還大概能解決排序的問題,何樂而不為,比方說我們在建表語句中只對name列的前10個字符進行索引可以這么寫:

    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+樹索引中只保留記錄的前10個字符的編碼,這種只索引字符串值的前綴的策略是我們非常鼓勵的,尤其是在字符串類型能存儲的字符比較多的時候。

    • 索引列前綴對排序的影響

    如果使用了索引列前綴,比方說前邊只把name列的前10個字符放到了二級索引中,下邊這個查詢可能就有點兒尷尬了:

    SELECT * FROM person_info ORDER BY name LIMIT 10;

    因為二級索引中不包含完整的name列信息,所以無法對前十個字符相同,后邊的字符不同的記錄進行排序,也就是使用索引列前綴的方式無法支持使用索引排序,只好乖乖的用文件排序嘍。

    讓索引列在比較表達式中單獨出現

    假設表中有一個整數列my_col,我們為這個列建立了索引。下邊的兩個WHERE子句雖然語義是一致的,但是在效率上卻有差別:

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

    所以結論就是:如果索引列在比較表達式中不是以單獨列的形式出現,而是以某個表達式,或者函數調用形式出現的話,是用不到索引的。

    主鍵插入順序

    我們知道,對于一個使用InnoDB存儲引擎的表來說,在我們沒有顯式的創建索引時,表中的數據實際上都是存儲在聚簇索引的葉子節點的。而記錄又是存儲在數據頁中的,數據頁和記錄又是按照記錄主鍵值從小到大的順序進行排序,所以如果我們插入的記錄的主鍵值是依次增大的話,那我們每插滿一個數據頁就換到下一個數據頁繼續插,而如果我們插入的主鍵值忽大忽小的話,這就比較麻煩了,假設某個數據頁存儲的記錄已經滿了,它存儲的主鍵值在1~100之間:

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

    可這個數據頁已經滿了啊,再插進來咋辦呢?我們需要把當前頁面分裂成兩個頁面,把本頁中的一些記錄移動到新創建的這個頁中。頁面分裂和記錄移位意味著什么?意味著:性能損耗!所以如果我們想盡量避免這樣無謂的性能損耗,最好讓插入的記錄的主鍵值依次遞增,這樣就不會發生這樣的性能損耗了。所以我們建議:讓主鍵具有AUTO_INCREMENT,讓存儲引擎自己為表生成主鍵,而不是我們手動插入?,比方說我們可以這樣定義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屬性,在插入記錄時存儲引擎會自動為我們填入自增的主鍵值。

    冗余和重復索引

    有時候有的同學有意或者無意的就對同一個列創建了多個索引,比方說這樣寫建表語句:

    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)) );

    我們知道,通過idx_name_birthday_phone_number索引就可以對name列進行快速搜索,再創建一個專門針對name列的索引就算是一個冗余索引,維護這個索引只會增加維護的成本,并不會對搜索有什么好處。

    另一種情況,我們可能會對某個列重復建立索引,比方說這樣:

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

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

    總結

    上邊只是我們在創建和使用B+樹索引的過程中需要注意的一些點,后邊我們還會陸續介紹更多的優化方法和注意事項,敬請期待。本集內容總結如下:

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

    以上就是Mysql事務隔離級別的詳細說明與實現原理,這是別的博主的一篇文章,我覺得寫得非常簡單易懂且詳細,就不再造輪子,分享給大家,還有更多興趣的,可以通過下面的鏈接,訪問原文,系統的了解mysql的本質。

    版權聲明:本文為給予掘金博主「小孩子」的原創文章,進行的簡化說明,詳細的可以參考掘金小冊

    總結

    以上是生活随笔為你收集整理的Mysql B+树索引的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    麻豆影视在线播放 | 日日爱av | 在线视频精品 | 国产色a在线观看 | 国产精品一区二区在线 | 在线中文字幕一区二区 | 黄网站色视频 | 久久婷婷一区 | 亚洲91在线 | 视频高清 | 麻豆视频国产 | 香蕉97视频观看在线观看 | 高清av中文字幕 | 久久久精品一区二区三区 | 日韩欧美xx | a级片在线播放 | 国产精品99久久久久久有的能看 | 99re视频在线观看 | a电影免费看 | 综合色亚洲| 国产人成精品一区二区三 | 国模视频一区二区 | 国产精品成人久久久久 | 久久九九久久九九 | 色福利网站 | 97在线精品国自产拍中文 | 亚洲每日更新 | 亚洲欧美日韩中文在线 | 区一区二区三区中文字幕 | av免费看在线 | 亚洲国产手机在线 | 国产一区二区综合 | 在线不卡中文字幕播放 | 99久久精品免费看国产四区 | 亚洲日本一区二区在线 | 久久久久久欧美二区电影网 | 国产视频中文字幕 | 久久er99热精品一区二区 | 国产精品久久人 | 日本在线视频一区二区三区 | 久久激情五月激情 | 天天干 夜夜操 | 国产欧美高清 | 黄色毛片视频免费 | 亚洲高清久久久 | 日韩av电影一区 | 久久久久国产a免费观看rela | 国产一级三级 | 中文字幕在线视频一区二区 | 国产精品一区二区三区在线免费观看 | 国产一级视频 | 午夜视频在线观看欧美 | 日韩天天综合 | 精品视频123区在线观看 | 99日精品| 五月天激情综合网 | 久久精品日韩 | 免费网站污 | 亚洲欧美激情插 | 国产综合小视频 | 日韩在线视频网站 | 亚洲欧美精品一区二区 | 日韩婷婷 | 国产91区| 欧美精品在线观看免费 | 国产中出在线观看 | 少妇精品久久久一区二区免费 | 日韩精品1区2区 | 97免费在线观看视频 | av色图天堂网 | 婷婷国产在线 | 国产亚洲精品成人av久久影院 | 精品成人在线 | av观看在线观看 | 国产精品久久久久久久av电影 | 欧美少妇xxx | 99精品在线免费 | 久久久久久免费 | 天天玩天天干天天操 | 国产精品久久久久久久久久久久午夜 | 国产亚洲精品久久久久久无几年桃 | 国内精品视频久久 | 久久精品视频免费 | 最近最新最好看中文视频 | 日韩在线中文字幕视频 | av电影不卡在线 | 一区二区视频在线免费观看 | 国产精品亚洲视频 | 成人a级大片 | 久久久久久久久综合 | 精品在线亚洲视频 | 日韩免费一区二区在线观看 | 在线免费观看视频你懂的 | 高清一区二区 | 婷婷性综合 | 亚洲精品在线一区二区三区 | 亚洲一区二区三区毛片 | 99视频在线精品免费观看2 | 国产日韩视频在线播放 | 综合成人在线 | 成年人app网址 | 欧美日韩中文字幕视频 | 国产精品 日韩 欧美 | 一区二区视频在线观看免费 | 男女拍拍免费视频 | 中文字幕在线视频一区二区三区 | 日韩网站免费观看 | 97免费视频在线播放 | 园产精品久久久久久久7电影 | 天天操天天干天天干 | 国内精品免费久久影院 | 正在播放久久 | 四虎国产精品永久在线国在线 | 日日碰狠狠添天天爽超碰97久久 | 欧美日韩一级在线 | 国内精品久久久久久久影视麻豆 | 狠狠操导航 | 97在线观看免费高清完整版在线观看 | 婷婷激情5月天 | 永久av免费在线观看 | 日韩中文字幕91 | 国产91成人在在线播放 | 在线成人高清电影 | 操操日 | 精品国产自在精品国产精野外直播 | 欧美美女视频在线观看 | 亚洲永久国产精品 | 久久综合亚洲鲁鲁五月久久 | 欧美成人性网 | 欧美精品在线观看免费 | 亚洲精品色 | 久久久久在线观看 | 五月婷婷狠狠 | 亚洲视频网站在线观看 | 日韩免费三级 | 奇米网777 | 亚洲欧美经典 | 久久视频免费在线 | 在线观看视频一区二区 | 香蕉精品视频在线观看 | 欧美日韩二三区 | 国产第页 | 欧美国产日韩一区二区三区 | 欧美日韩在线第一页 | av大全在线看 | 最新av在线播放 | 久久久国产日韩 | 欧美日韩中文在线视频 | 特黄特色特刺激视频免费播放 | 亚洲国产最新 | 免费av网站观看 | 探花视频在线观看免费 | 天天操天天舔天天干 | 99精品一区二区三区 | 日韩电影在线视频 | 国产精品原创视频 | 成人av视屏 | 1024手机基地在线观看 | 肉色欧美久久久久久久免费看 | 蜜桃视频日韩 | 亚洲欧美在线观看视频 | 伊人成人久久 | 色成人亚洲| 国产视频在线免费 | 久久久久久国产精品 | 国产97视频在线 | 中文字幕观看视频 | 视频在线99re | 婷婷狠狠操 | 国产精品一区二区中文字幕 | 黄色在线观看免费 | a级国产乱理论片在线观看 特级毛片在线观看 | 久久国内视频 | 91福利视频久久久久 | 国产精品一区二区三区99 | 免费a级毛片在线看 | 国产啊v在线观看 | 91在线九色 | 狠狠躁夜夜躁人人爽超碰91 | 91av观看 | av电影免费在线播放 | 天天艹天天 | 色噜噜色噜噜 | 97av影院| 婷婷久操| 午夜视频不卡 | 成年人黄色免费看 | 国产精品6 | 在线观看91久久久久久 | 午夜精品久久久久久99热明星 | 午夜久草 | 亚洲精品在线观看不卡 | 国产高清视频在线 | 国产一级做a爱片久久毛片a | 久久精品视频免费 | 碰天天操天天 | 超碰国产在线播放 | 久久国产精品影片 | 欧美另类亚洲 | 夜夜夜| 手机在线黄色网址 | 高清一区二区三区 | 最近中文字幕免费大全 | 亚洲人视频在线 | 五月婷婷综 | www.操.com| 婷婷av电影| 天天干天天做天天爱 | 国产精品国产亚洲精品看不卡 | 婷婷丁香社区 | 亚洲成人av片在线观看 | 免费在线视频一区二区 | 国产黄色美女 | 久免费 | 成人资源在线 | 久久成年人 | 午夜精品久久一牛影视 | 久久久精品影视 | 国产成人精品一区二区三区福利 | 99热9| 国产福利免费在线观看 | 国产一区视频导航 | 免费在线91| 国产精品黄色 | 亚洲五月| 国产v在线 | 91久久精品一区二区二区 | av高清在线观看 | 成人免费 在线播放 | 国产男女无遮挡猛进猛出在线观看 | 国产精品久久麻豆 | 成人免费在线播放视频 | aaa免费毛片| 黄色大全免费观看 | 国产手机免费视频 | 亚洲国内精品 | 国产精品丝袜久久久久久久不卡 | 婷婷在线观看视频 | 高潮毛片无遮挡高清免费 | 日韩理论电影网 | 日韩偷拍精品 | 久久深夜福利免费观看 | 最新免费中文字幕 | 99精品国产免费久久久久久下载 | 日韩精品电影在线播放 | www.日日操.com| 精品在线免费视频 | 成人黄色小说在线观看 | 国产黄免费在线观看 | 探花国产在线 | 精品日韩av| 91精品国产福利在线观看 | 午夜精品久久久 | 日韩理论在线观看 | 成人国产网站 | 91丨九色丨国产在线 | 久久久久久久久影视 | 99久久精品免费 | 国产亚洲精品久久久久秋 | 日本高清免费中文字幕 | 欧美十八 | 精品欧美一区二区精品久久 | 91麻豆精品国产午夜天堂 | 久久精品日本啪啪涩涩 | 国产免费高清视频 | 国产一区二区三区在线免费观看 | 日韩精品不卡 | 亚洲激情精品 | 中文字幕在线视频第一页 | 亚洲精品www久久久 www国产精品com | 99视频在线看 | 在线黄色毛片 | www.看片网站 | av在线免费观看黄 | 久久久天堂 | 99视频国产精品 | 久久久精品久久 | 欧美成人精品欧美一级乱 | 福利一区在线 | 久久99久久99精品免观看粉嫩 | 久久人人爽人人爽人人片 | 日韩精品一区二区三区免费观看视频 | 国产成免费视频 | 美女国产 | 新版资源中文在线观看 | 国产综合福利在线 | 国产精品久久久久久久久久东京 | 亚洲国产无 | 在线99热 | 欧美日韩高清在线观看 | 国语对白少妇爽91 | 天堂网av在线 | 国产一区电影在线观看 | 在线观看视频你懂得 | 99久在线精品99re8热视频 | 亚洲精品久久在线 | 色插综合 | 97视频人人澡人人爽 | 91丨九色丨蝌蚪丨老版 | 91人人澡人人爽人人精品 | 国产午夜三级 | 国产日韩精品视频 | 中国一区二区视频 | 亚洲电影一区二区 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 久久国产精品久久久久 | 久草在线观 | 在线亚洲免费视频 | 日韩三级免费观看 | 国产xxxxx在线观看 | av天天澡天天爽天天av | 日韩欧美一区二区三区视频 | 黄色大片国产 | 美女福利视频在线 | av在线在线 | 日韩在线视频在线观看 | 高清色免费 | 88av网站 | 丁香五月缴情综合网 | 久久精品理论 | 欧美一级大片在线观看 | av网址在线播放 | 伊人五月在线 | 日日干天天爽 | 中文字幕在线日亚洲9 | 国产97视频在线 | 国产91影院| 激情网五月 | 亚洲 中文字幕av | 亚洲国产三级 | 最新极品jizzhd欧美 | 亚洲丝袜一区二区 | 中文字幕免费成人 | 国产精品人成电影在线观看 | 亚洲妇女av | 亚洲色图 校园春色 | 人人干免费 | 日韩精品中文字幕一区二区 | 日本中文字幕久久 | 92中文资源在线 | 日韩最新av在线 | 中文国产在线观看 | 五月开心网 | 亚洲va天堂va欧美ⅴa在线 | 黄色中文字幕 | 免费观看9x视频网站在线观看 | 欧美日韩午夜在线 | 天天操夜夜操国产精品 | 亚洲欧美日韩国产 | 日韩免费一级电影 | 婷婷国产一区二区三区 | 日本黄色a级大片 | 国产不卡高清 | 国产日韩在线视频 | 久久99网 | 奇米777777 | 国产亚洲精品久久久久久网站 | 日韩专区在线 | 日韩性片| 69国产盗摄一区二区三区五区 | 日韩有码中文字幕在线 | 又黄又爽又湿又无遮挡的在线视频 | 国产亚洲精品久久久久久移动网络 | 久久精品视频中文字幕 | 日韩欧美在线免费观看 | 天天摸天天舔天天操 | 西西444www高清大胆 | 中文字幕一区二区三区在线视频 | 日韩a级黄色片 | 日韩精品五月天 | 日本不卡一区二区三区在线观看 | 91精品久久久久久综合乱菊 | 国产精品免费久久 | www.国产高清 | 久久免费的视频 | 国产精品免费观看视频 | 91成人久久 | 成人午夜久久 | 日韩精品一区二区电影 | 91系列在线观看 | 91麻豆精品国产91久久久无限制版 | 久久久精品一区二区三区 | 综合色婷婷 | av网站大全免费 | 在线 欧美 日韩 | 天天插天天狠天天透 | 日韩免费观看av | 狠狠躁夜夜躁人人爽超碰97香蕉 | 香蕉久久国产 | 91看片看淫黄大片 | 色综合久久久久 | 婷婷久久综合网 | 粉嫩高清一区二区三区 | 国产精品高潮久久av | www最近高清中文国语在线观看 | 中文字幕在线播出 | 99久久婷婷国产综合亚洲 | 日韩免费一级a毛片在线播放一级 | 国产精品久久久777 成人手机在线视频 | 国产一区二区在线播放视频 | 狠狠躁天天躁综合网 | 日本精品视频在线观看 | 在线不卡a | 欧美少妇的秘密 | 国产 日韩 在线 亚洲 字幕 中文 | 精品在线观看一区二区三区 | 一级大片在线观看 | 国产高清在线不卡 | 日本黄色一级电影 | 日韩免费三级 | 中文字幕亚洲欧美日韩 | 涩五月婷婷 | 一区二区三区免费在线观看 | 欧美日韩高清一区 | 日韩欧美观看 | 欧美一级视频免费 | 亚洲激情六月 | 四虎影视8848dvd | 亚洲国产成人在线观看 | 97国产在线播放 | 日韩伦理一区二区三区av在线 | 99视频在线播放 | 1024在线看片 | 精品九九九 | 九九免费在线观看视频 | 免费高清男女打扑克视频 | 久草在线视频在线观看 | 99久久久久国产精品免费 | 精品字幕| 亚洲经典在线 | 国产不卡在线视频 | 国产午夜一级毛片 | 日韩黄在线观看 | 福利视频一区二区 | 99精品国产99久久久久久福利 | 国产精品国产亚洲精品看不卡15 | 国产成人精品一区二区三区在线 | 丁香婷婷社区 | 99免费精品视频 | 黄色亚洲大片免费在线观看 | 欧美日韩在线观看一区二区 | 丁香在线视频 | 成人黄视频 | 久久人人97超碰精品888 | 久久av免费观看 | 久久精品第一页 | 91黄在线看 | 国产韩国精品一区二区三区 | 日韩精品黄 | 亚洲视频在线免费观看 | 香蕉影院在线播放 | 国产伦理久久精品久久久久_ | 日韩视频一| 久久午夜精品影院一区 | av黄色在线 | 亚洲色视频 | 欧洲精品在线视频 | 免费黄色看片 | 午夜免费福利片 | 国内精品国产三级国产aⅴ久 | 蜜桃av人人夜夜澡人人爽 | 人人插人人爱 | 午夜影院一级 | 99国产精品久久久久老师 | 国产高清免费观看 | 美女网站视频一区 | 欧美亚洲一级片 | 欧美日韩中文在线观看 | 国产91aaa| 国产一级特黄毛片在线毛片 | 午夜狠狠干 | 久久亚洲私人国产精品va | 91精品国产电影 | 免费在线激情电影 | 91成人在线网站 | 在线观看中文字幕av | 黄色av电影在线观看 | 韩国在线一区二区 | 青草草在线视频 | 啪啪凸凸| 日韩久久视频 | 久久艹人人 | 亚洲一区二区精品 | 丁香花在线视频观看免费 | 精品一区二区在线播放 | 亚洲一区久久 | 久久综合色影院 | 精品国产伦一区二区三区 | av观看久久久 | 成人黄色片在线播放 | 天堂中文在线视频 | 亚洲激情在线 | 97成人免费视频 | 日韩美av在线 | 久久看免费视频 | 青春草视频 | 深爱五月激情网 | 亚洲 欧美 精品 | 9999精品视频 | 欧美国产日韩一区二区三区 | 精品久久一区二区 | av电影中文| 婷婷网址 | 18国产精品福利片久久婷 | 免费黄色网址大全 | 免费成人av在线看 | 国产精品久久久久久久久久久久午夜 | 中文字幕91在线 | 国产精品视频永久免费播放 | 五月天天色| 中文字幕一区二区三区在线观看 | 久久精品麻豆 | 日韩精品久久久久久中文字幕8 | 国产精品女人久久久 | 国产99精品在线观看 | 91黄色免费网站 | 爱情影院aqdy鲁丝片二区 | 中文字幕中文字幕 | 美国av片在线观看 | 日日干夜夜爱 | 日韩中文字幕免费 | 国产成人精品一区二区三区在线 | 国产精品99精品久久免费 | 黄色三级免费看 | 免费在线观看视频一区 | 91在线亚洲| 色999精品 | 久草资源在线观看 | 亚洲精品麻豆 | 欧美性视频网站 | 丁香激情五月婷婷 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 激情狠狠干 | 在线观看久久 | 成 人 黄 色视频免费播放 | 亚洲一区 影院 | 激情五月在线 | 日韩在线资源 | 插插插色综合 | 在线影院 国内精品 | 一区二区三区在线免费观看 | 亚洲黄色大片 | 九九综合九九 | 亚洲免费av片 | 国产精品自在线 | 免费观看国产视频 | 六月丁香在线观看 | 久久久综合香蕉尹人综合网 | 中文字幕精品久久 | 成年人免费av | 亚洲精品视频第一页 | 精品日韩中文字幕 | 91av短视频| 精品国产一区二区三区免费 | 成人av视屏| 国产亚洲在 | 国产一区免费视频 | 精品国产人成亚洲区 | www黄色软件 | 深爱激情综合网 | 婷婷丁香导航 | 麻豆视频免费在线 | 亚洲精品视频在 | 日韩欧美久久 | 五月天婷亚洲天综合网鲁鲁鲁 | 久久人人97超碰精品888 | 黄色影院在线免费观看 | 五月网婷婷 | 97视频在线观看成人 | 涩涩资源网 | 成人va视频 | 美女一区网站 | 国产在线看一区 | 国产精品爽爽久久久久久蜜臀 | 免费看国产a | 激情久久综合 | 97人人澡人人添人人爽超碰 | 国产福利不卡视频 | 免费看一及片 | 91久久精品日日躁夜夜躁国产 | 精品极品在线 | 久草在线在线视频 | 精品久久网 | 欧美日韩高清一区二区 国产亚洲免费看 | 国产97色| 欧美精品成人在线 | 国产人免费人成免费视频 | 国产美女视频 | 日韩免费中文字幕 | 99久久婷婷国产 | 激情欧美xxxx | 国产福利中文字幕 | 天天爱天天舔 | 亚洲天堂网视频在线观看 | 香蕉视频4aa | 国模视频一区二区三区 | av福利在线导航 | 久久免费福利 | 久一久久 | av日韩中文| 国产一区二区三区午夜 | 亚洲免费av网站 | 欧美在线观看视频免费 | 中文字幕精品一区久久久久 | 视频高清| 亚洲在线看 | 毛片无卡免费无播放器 | 国产三级视频在线 | av在线播放免费 | 免费精品国产va自在自线 | 麻豆91精品视频 | 国产手机在线视频 | 亚洲国内精品 | 国产小视频在线 | 日韩在线一区二区免费 | 免费在线看成人av | 久久精品国产亚洲 | 天天色棕合合合合合合 | 日躁夜躁狠狠躁2001 | 在线中文字母电影观看 | 亚洲日本精品视频 | 中文字幕欧美日韩va免费视频 | 午夜视频黄 | 一区二区三区四区在线免费观看 | 国产又粗又猛又黄视频 | 美女视频黄免费 | 国产精品aⅴ | 欧美精彩视频 | 日本久久久久久科技有限公司 | 91成人破解版| 在线观看一区二区精品 | 国产精品亚洲综合久久 | www.久久久.cum | 成人精品视频 | 国产精品美女久久久 | 久久久久福利视频 | 亚洲一级理论片 | 婷婷丁香色综合狠狠色 | 国产福利91精品一区二区三区 | 久久久久99精品国产片 | 人人澡视频 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 精品国产自在精品国产精野外直播 | 国产香蕉视频在线观看 | 精品国产观看 | 久久综合久久88 | 五月婷婷深开心 | 黄毛片在线观看 | 91污污视频在线观看 | 免费色视频网址 | 久久99热这里只有精品国产 | 日日操狠狠干 | 韩国av一区二区三区在线观看 | 一区二区三区高清在线观看 | 天天综合网天天 | 免费观看9x视频网站在线观看 | 日韩欧美国产成人 | 天堂中文在线播放 | 美女在线免费视频 | 国产精品国内免费一区二区三区 | 免费91麻豆精品国产自产在线观看 | 亚洲精品乱码久久 | 欧洲精品在线视频 | 综合久久网 | 国产精品午夜久久久久久99热 | 一级特黄aaa大片在线观看 | 天天操天天干天天爱 | av久久久久久 | 98涩涩国产露脸精品国产网 | 久久久久福利视频 | 久久精品视频播放 | 久久精久久精 | 欧美一级免费片 | 中文字幕在线观看免费高清完整版 | 日本婷婷色 | 色99在线 | 亚洲精品国产拍在线 | 青青河边草免费直播 | 国产精品女教师 | 欧美日韩成人 | 成人av中文字幕在线观看 | 91看片成人 | 成人中文字幕+乱码+中文字幕 | 97超碰在线久草超碰在线观看 | 911亚洲精品第一 | 国产午夜精品理论片在线 | 免费日韩一区 | 久久激情电影 | 91成人精品国产刺激国语对白 | 一区二区中文字幕在线 | 97精品国产91久久久久久久 | 国产精品9999久久久久仙踪林 | 国产精品第三页 | avav片| 久久精品99国产国产精 | 国产亚洲午夜高清国产拍精品 | 热re99久久精品国产99热 | 久久8 | 精品久久久久久久久中文字幕 | 激情小说网站亚洲综合网 | 国产午夜精品一区二区三区在线观看 | 国产日产精品一区二区三区四区的观看方式 | 日韩电影一区二区在线观看 | 国内丰满少妇猛烈精品播放 | 天堂成人在线 | 日日干天天 | 一级黄色片在线免费看 | 亚洲h在线播放在线观看h | 久久精品视频免费 | 91精品视屏 | 欧美一级爽| www日韩在线| 欧美资源在线观看 | 亚洲精品99 | 美女视频一区 | 国产精品久久艹 | 日日综合 | 国内精品一区二区 | 婷婷五天天在线视频 | 精品在线观看一区二区三区 | 国产人成免费视频 | 最新中文在线视频 | 天堂av观看 | 国内外成人在线视频 | 亚洲九九| 在线播放 日韩专区 | 狠狠干婷婷 | 国产欧美最新羞羞视频在线观看 | 我要看黄色一级片 | 成人免费在线播放视频 | 在线最新av | 欧美精品被 | 激情综合六月 | 波多野结衣在线观看一区 | 日韩理论影院 | 亚洲精品久久久蜜臀下载官网 | av免费电影在线 | 成人三级视频 | 黄色成人91| 日本女人的性生活视频 | 亚洲成人影音 | 久久久久久久99精品免费观看 | 中文字幕久久网 | 欧美日韩观看 | 麻豆av一区二区三区在线观看 | 国产一区二区精品 | 精品国产亚洲一区二区麻豆 | 久久免费精品 | 久久艹欧美| 久久久久久久免费观看 | av三级在线播放 | 肉色欧美久久久久久久免费看 | 一级片免费观看 | 97在线观看免费 | 欧美a视频在线观看 | 色综合天天视频在线观看 | 成人国产电影在线观看 | av成人在线电影 | 99久高清在线观看视频99精品热在线观看视频 | 国产成人精品一区二区三区福利 | 精品久久99 | 国产一级黄色电影 | 欧美精品一区二区三区一线天视频 | 911国产在线观看 | 久久视频6| 视频一区二区三区视频 | 亚洲三级网站 | 一二三久久久 | 九九九热精品 | 天天射天天干 | 视频一区二区免费 | 91精品欧美| 日本精品va在线观看 | 国产精品一区二区三区在线免费观看 | 五月天最新网址 | 久人人 | www夜夜操| 久久精品久久精品 | 色多多污污 | 亚洲一级免费电影 | 亚洲精品中文在线资源 | 在线观看中文字幕一区二区 | 在线中文字幕av观看 | 97视频免费在线 | 97日日碰人人模人人澡分享吧 | 99 视频 高清 | 91精品国产92久久久久 | 在线观看一 | 九九激情视频 | 成人毛片100免费观看 | 国产少妇在线观看 | 叶爱av在线 | 黄色大片免费网站 | 黄色大片av | 久久精品8| 国产精品18久久久久vr手机版特色 | 亚洲自拍偷拍色图 | 亚洲精品国产综合99久久夜夜嗨 | 日本公妇在线观看高清 | 激情网站五月天 | 久久精品成人 | 日p在线观看 | 国产精品免费高清 | 久久久久国产精品免费网站 | 俺要去色综合狠狠 | 午夜视频久久久 | 玖玖在线观看视频 | 黄色av网站在线观看免费 | 国产免费专区 | 成人一级视频在线观看 | 视频在线观看入口黄最新永久免费国产 | 国产不卡视频 | 人人草在线观看 | 在线观看精品一区 | 丁香激情综合久久伊人久久 | 激情欧美丁香 | 99精品久久久 | 在线观看视频黄色 | 久久国产精品免费看 | 色婷婷狠狠18 | 日韩理论电影在线观看 | 日韩午夜电影院 | 国产一区二区久久久久 | 日韩videos| 五月天激情开心 | 人人艹人人 | 国产精品国产亚洲精品看不卡 | 天堂av官网 | 天天婷婷 | 国产精品初高中精品久久 | 91超在线| 国产日韩欧美在线免费观看 | 国产成人精品在线 | 激情五月看片 | av中文字幕在线观看网站 | 婷婷综合导航 | 色www精品视频在线观看 | 久久婷婷丁香 | 国产精品s色 | 日韩精品视频免费专区在线播放 | 91麻豆精品国产自产在线 | 久久在线观看 | 五月天网页 | 亚洲精品videossex少妇 | 天天干天天拍天天操天天拍 | 亚洲一级久久 | 日韩欧美视频在线免费观看 | 亚洲精品视频中文字幕 | 超碰av在线播放 | 中文电影网| 色婷婷av国产精品 | 99久久99久久综合 | 成年人免费在线观看网站 | 国产在线中文 | 人人干免费 | 91亚洲精品久久久中文字幕 | 日日爱网站| 黄色小说免费观看 | 成人免费在线看片 | 成人网色 | 欧美日韩国产精品一区二区亚洲 | 欧美在线一二 | 在线色网站| 久久婷婷综合激情 | 国产精品美女999 | 激情中文在线 | 一级黄色电影网站 | 欧美动漫一区二区三区 | 国产一区二区三区免费观看视频 | 91麻豆精品国产91久久久使用方法 | 一区二区在线电影 | 人人爱天天操 | 国产四虎在线 | 六月天色婷婷 | 国产精品去看片 | 国产一区国产精品 | 六月丁香色婷婷 | 国产综合精品久久 | 综合视频在线 | 四虎成人精品永久免费av | 在线观看av小说 | 国产精品理论视频 | 国产精品中文久久久久久久 | 亚洲国产成人精品久久 | 免费观看9x视频网站在线观看 | 青青河边草免费 | 国内精品久久久久久久影视简单 | 中文字幕在线观看免费观看 | 国内精品久久久久影院优 | 欧美日本在线视频 | 国内99视频 | 色婷婷 亚洲 | 在线免费观看视频 | 亚洲va在线va天堂 | 国产三级香港三韩国三级 | 日韩一区二区三免费高清在线观看 | 国产乱码精品一区二区蜜臀 | 国产美腿白丝袜足在线av | 人人爽人人av | 国产成人在线精品 | 日韩在线视频线视频免费网站 | 中文字幕免费在线看 | 91精品蜜桃 | 亚洲精品福利在线 | av视屏在线播放 | 国产精品涩涩屋www在线观看 | 视频三区在线 | 久久精品看 | 久久免费在线观看 | 亚洲精品久久激情国产片 | 在线观看免费av片 | 91麻豆精品一区二区三区 | 国产又粗又猛又色又黄视频 | 91综合久久一区二区 | 亚洲最大av网站 | 免费久草视频 | 91视频88av | 久草网站在线观看 | 精品999| 一区二区三区在线观看中文字幕 | 欧美久久久久久久久久久 | 日韩精品91偷拍在线观看 | 最新婷婷色 | 成片人卡1卡2卡3手机免费看 | 婷婷色在线观看 | 四虎在线免费观看视频 | 一区二区欧美日韩 | 久久久在线观看 | 国产黄色片久久 | 久久精品视频3 | 狠狠干 狠狠操 | 免费精品国产va自在自线 | 免费看国产曰批40分钟 | 国产精品一区二区三区四区在线观看 | 99久热在线精品视频观看 | 日韩欧美高清不卡 | 色综合天天天天做夜夜夜夜做 | 韩国av在线| 美女黄久久 | 欧美 日韩 国产 成人 在线 | 国产亚洲精品久久久久久无几年桃 | 日韩成人欧美 | 六月激情丁香 | 久久天天躁夜夜躁狠狠85麻豆 | 国产传媒中文字幕 | 久久久18 | 性日韩欧美在线视频 | 色婷婷99 | 免费看一级黄色 | 五月婷综合| 爱情影院aqdy鲁丝片二区 | 国产在线一卡 | 亚洲综合成人专区片 | 成人影片在线播放 | 在线观看国产日韩欧美 | 色狠狠婷婷 | 91成人免费看| 久草在线最新免费 | 欧美成人精品在线 | 精品亚洲免费 | 99久热在线精品 | 精品视频中文字幕 | 亚洲成人精品久久 | 三三级黄色片之日韩 | 在线观看中文字幕一区二区 | 色综合www| 在线高清一区 | 午夜18视频在线观看 | 二区三区中文字幕 | 日韩久久精品一区二区三区 | 国产精品精品国产色婷婷 | 99在线观看免费视频精品观看 | 综合色婷婷| 精品国产乱码一区二 | 久久精品电影网 | 亚洲精品国产精品国 | 中文字幕乱码日本亚洲一区二区 | 婷婷六月激情 | 涩涩网站在线 | 又黄又刺激的网站 | 国产精品一区二区三区四区在线观看 | 欧美做受高潮电影o | 蜜臀久久99精品久久久酒店新书 | 日本久久综合网 | 美女网站在线观看 | 成人黄色在线电影 | 99这里只有精品视频 | 午夜精品av在线 | 中文字幕字幕中文 | 欧美成人精品欧美一级乱 | 国产99久久久国产 | 国产亚洲免费的视频看 | 久久好看免费视频 | 天堂在线视频免费观看 | 在线视频一二三 | 久久久久亚洲国产精品 | 国产一级a毛片视频爆浆 | 国产成人精品一区一区一区 |