精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

不要再問我 In,Exists 走不走索引了...

運維 數(shù)據(jù)庫運維
最近,有一個業(yè)務(wù)需求,給我一份數(shù)據(jù) A ,把它在數(shù)據(jù)庫 B 中存在,而又比 A 多出的部分算出來。由于數(shù)據(jù)比較雜亂,我這里簡化模型。

[[339313]]

前言

最近,有一個業(yè)務(wù)需求,給我一份數(shù)據(jù) A ,把它在數(shù)據(jù)庫 B 中存在,而又比 A 多出的部分算出來。由于數(shù)據(jù)比較雜亂,我這里簡化模型。

然后就會發(fā)現(xiàn),我去,這不就是 not in ,not exists 嘛。

那么問題來了,in, not in , exists , not exists 它們有什么區(qū)別,效率如何?

曾經(jīng)從網(wǎng)上聽說,in 和 exists 不會走索引,那么事實真的是這樣嗎?

帶著疑問,我們研究下去。

注意: 在說這個問題時,不說明 MySQL 版本的都是耍流氓,我這里用的是 5.7.18 。

用法講解

為了方便,我們創(chuàng)建兩張表 t1 和 t2 。并分別加入一些數(shù)據(jù)。(id為主鍵,name為普通索引)

  1. -- t1 
  2. DROP TABLE IF EXISTS `t1`; 
  3. CREATE TABLE `t1` ( 
  4.   `id` int(11) NOT NULL AUTO_INCREMENT, 
  5.   `namevarchar(255) DEFAULT NULL
  6.   `address` varchar(255) DEFAULT NULL
  7.   PRIMARY KEY (`id`), 
  8.   KEY `idx_t1_name` (`name`(191)) USING BTREE 
  9. ) ENGINE=InnoDB AUTO_INCREMENT=1009 DEFAULT CHARSET=utf8mb4; 
  10.  
  11. INSERT INTO `t1` VALUES ('1001''張三''北京'), ('1002''李四''天津'), ('1003''王五''北京'), ('1004''趙六''河北'), ('1005''杰克''河南'), ('1006''湯姆''河南'), ('1007''貝爾''上海'), ('1008''孫琪''北京'); 
  12.  
  13. -- t2 
  14. DROP TABLE IF EXISTS `t2`; 
  15. CREATE TABLE `t2`  ( 
  16.   `id` int(11) NOT NULL AUTO_INCREMENT, 
  17.   `namevarchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL
  18.   `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL
  19.   PRIMARY KEY (`id`) USING BTREE, 
  20.   INDEX `idx_t2_name`(`name`(191)) USING BTREE 
  21. ) ENGINE = InnoDB AUTO_INCREMENT = 1014 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic
  22.  
  23. INSERT INTO `t2` VALUES (1001, '張三''北京'); 
  24. INSERT INTO `t2` VALUES (1004, '趙六''河北'); 
  25. INSERT INTO `t2` VALUES (1005, '杰克''河南'); 
  26. INSERT INTO `t2` VALUES (1007, '貝爾''上海'); 
  27. INSERT INTO `t2` VALUES (1008, '孫琪''北京'); 
  28. INSERT INTO `t2` VALUES (1009, '曹操''魏國'); 
  29. INSERT INTO `t2` VALUES (1010, '劉備''蜀國'); 
  30. INSERT INTO `t2` VALUES (1011, '孫權(quán)''吳國'); 
  31. INSERT INTO `t2` VALUES (1012, '諸葛亮''蜀國'); 
  32. INSERT INTO `t2` VALUES (1013, '典韋''魏國'); 

 

那么,對于當(dāng)前的問題,就很簡單了,用 not in 或者 not exists 都可以把 t1 表中比 t2 表多出的那部分?jǐn)?shù)據(jù)給挑出來。(當(dāng)然,t2 比 t1 多出來的那部分不算)

這里假設(shè)用 name 來匹配數(shù)據(jù)。

  1. select * from t1 where name not in (select name from t2); 
  2. 或者用 
  3. select * from t1 where not exists (select name from t2 where t1.name=t2.name); 

得到的結(jié)果都是一樣的。

 

但是,需要注意的是,not in 和 not exists 還是有不同點的。

在使用 not in 的時候,需要保證子查詢的匹配字段是非空的。如,此表 t2 中的 name 需要有非空限制。如若不然,就會導(dǎo)致 not in 返回的整個結(jié)果集為空。

例如,我在 t2 表中加入一條 name 為空的數(shù)據(jù)。

  1. INSERT INTO `t2` VALUES (1014, NULL'魏國'); 

則此時,not in 結(jié)果就會返回空。

 

另外需要明白的是, exists 返回的結(jié)果是一個 boolean 值 true 或者 false ,而不是某個結(jié)果集。因為它不關(guān)心返回的具體數(shù)據(jù)是什么,只是外層查詢需要拿這個布爾值做判斷。

區(qū)別是,用 exists 時,若子查詢查到了數(shù)據(jù),則返回真。用 not exists 時,若子查詢沒有查到數(shù)據(jù),則返回真。

由于 exists 子查詢不關(guān)心具體返回的數(shù)據(jù)是什么。因此,以上的語句完全可以修改為如下,

  1. -- 子查詢中 name 可以修改為其他任意的字段,如此處改為 1 。 
  2. select * from t1 where not exists (select 1 from t2 where t1.name=t2.name); 

從執(zhí)行效率來說,1 > column > * 。因此推薦用 select 1。(準(zhǔn)確的說應(yīng)該是常量值)

in, exists 執(zhí)行流程

1、 對于 in 查詢來說,會先執(zhí)行子查詢,如上邊的 t2 表,然后把查詢得到的結(jié)果和外表 t1 做笛卡爾積,再通過條件進行篩選(這里的條件就是指 name 是否相等),把每個符合條件的數(shù)據(jù)都加入到結(jié)果集中。

sql 如下,

  1. select * from t1 where name in (select name from t2); 

偽代碼如下:

  1. for(x in A){ 
  2.     for(y in B){ 
  3.      if(condition is true) {result.add();} 
  4.     } 

這里的 condition 其實就是對比兩張表中的 name 是否相同。

2、對于 exists 來說,是先查詢遍歷外表 t1 ,然后每次遍歷時,再檢查在內(nèi)表是否符合匹配條件,即檢查是否存在 name 相等的數(shù)據(jù)。

sql 如下,

  1. select * from t1 where name exists (select 1 from t2); 

偽代碼如下:

  1. for(x in A){ 
  2.   if(exists condition is true){result.add();} 

對應(yīng)于此例,就是從 id 為 1001 開始遍歷 t1 表 ,然后遍歷時檢查 t2 中是否有相等的 name 。

如 id=1001時,張三存在于 t2 表中,則返回 true,把 t1 中張三的這條記錄加入到結(jié)果集,繼續(xù)下次循環(huán)。id=1002 時,李四不在 t2 表中,則返回 false,不做任何操作,繼續(xù)下次循環(huán)。直到遍歷完整個 t1 表。

是否走索引?

針對網(wǎng)上說的 in 和 exists 不走索引,那么究竟是否如此呢?

我們在 MySQL 5.7.18 中驗證一下。(注意版本號哦)

單表查詢

首先,驗證單表的最簡單的情況。我們就以 t1 表為例,id為主鍵, name 為普通索引。

分別執(zhí)行以下語句,

  1. explain select * from t1 where id in (1001,1002,1003,1004); 
  2. explain select * from t1 where id in (1001,1002,1003,1004,1005); 
  3. explain select * from t1 where name in ('張三','李四'); 
  4. explain select * from t1 where name in ('張三','李四','王五'); 

為什么我要分別查不同的 id 個數(shù)呢?看截圖,

 

會驚奇的發(fā)現(xiàn),當(dāng) id 是四個值時,還走主鍵索引。而當(dāng) id 是五個值時,就不走索引了。這就很耐人尋味了。

再看 name 的情況,

 

同樣的當(dāng)值多了之后,就不走索引了。

所以,我猜測這個跟匹配字段的長度有關(guān)。按照漢字是三個字節(jié)來計算,且程序設(shè)計中喜歡用2的n次冪的尿性,這里大概就是以 16 個字節(jié)為分界點。

然而,我又以同樣的數(shù)據(jù),去我的服務(wù)器上查詢(版本號 5.7.22),發(fā)現(xiàn)四個id值時,就不走索引了。因此,估算這里的臨界值為 12 個字節(jié)。

不管怎樣,這說明了,在 MySQL 中應(yīng)該對 in 查詢的字節(jié)長度是有限制的。(沒有官方確切說法,所以,僅供參考)

多表涉及子查詢

我們主要是去看當(dāng)前的這個例子中的兩表查詢時, in 和 exists 是否走索引。

一、分別執(zhí)行以下語句,主鍵索引(id)和普通索引(name),在 in , not in 下是否走索引。

  1. explain select * from t1 where id in (select id from t2); --1 
  2. explain select * from t1 where name in (select name from t2); --2 
  3. explain select * from t1 where id not in (select id from t2); --3 
  4. explain select * from t1 where name not in (select name from t2); --4 

結(jié)果截圖如下,

1、t1 走索引,t2 走索引。

1

 

2、t1 不走索引,t2不走索引。(此種情況,實測若把name改為唯一索引,則t1也會走索引)

2

 

3、t1 不走索引,t2走索引。

3

 

4、t1不走索引,t2不走索引。

4

 

我滴天,這結(jié)果看起來亂七八糟的,好像走不走索引,完全看心情。

但是,我們發(fā)現(xiàn)只有第一種情況,即用主鍵索引字段匹配,且用 in 的情況下,兩張表才都走索引。

這個到底是不是規(guī)律呢?有待考察,且往下看。

二、接下來測試,主鍵索引和普通索引在 exists 和 not exists 下的情況。sql如下,

  1. explain select * from t1 where exists (select 1 from t2 where t1.id=t2.id); 
  2. explain select * from t1 where exists (select 1 from t2 where t1.name=t2.name); 
  3. explain select * from t1 where not exists (select 1 from t2 where t1.id=t2.id); 
  4. explain select * from t1 where not exists (select 1 from t2 where t1.name=t2.name); 

這個結(jié)果就非常有規(guī)律了,且看,

 

有沒有發(fā)現(xiàn), t1 表哪種情況都不會走索引,而 t2 表是有索引的情況下就會走索引。為什么會出現(xiàn)這種情況?

其實,上一小節(jié)說到了 exists 的執(zhí)行流程,就已經(jīng)說明問題了。

它是以外層表為驅(qū)動表,無論如何都會循環(huán)遍歷的,所以會全表掃描。而內(nèi)層表通過走索引,可以快速判斷當(dāng)前記錄是否匹配。

效率如何?

針對網(wǎng)上說的 exists 一定比 in 的執(zhí)行效率高,我們做一個測試。

分別在 t1,t2 中插入 100W,200W 條數(shù)據(jù)。

我這里,用的是自定義函數(shù)來循環(huán)插入,語句參考如下,(沒有把表名抽離成變量,因為我沒有找到方法,尷尬)

  1. -- 傳入需要插入數(shù)據(jù)的id開始值和數(shù)據(jù)量大小,函數(shù)返回結(jié)果為最終插入的條數(shù),此值正常應(yīng)該等于數(shù)據(jù)量大小。 
  2. -- id自增,循環(huán)往 t1 表添加數(shù)據(jù)。這里為了方便,id、name取同一個變量,address就為北京。 
  3. delimiter //  
  4. drop function if exists insert_datas1// 
  5. create function insert_datas1(in_start int(11),in_len int(11)) returns int(11) 
  6. begin   
  7.   declare cur_len int(11) default 0; 
  8.   declare cur_id int(11); 
  9.   set cur_id = in_start; 
  10.   
  11.   while cur_len < in_len do 
  12.      insert into t1 values(cur_id,cur_id,'北京'); 
  13.   set cur_len = cur_len + 1; 
  14.   set cur_id = cur_id + 1; 
  15.   end while;  
  16.   return cur_len; 
  17. end   
  18. // 
  19. delimiter ; 
  20. -- 同樣的,往 t2 表插入數(shù)據(jù) 
  21. delimiter //  
  22. drop function if exists insert_datas2// 
  23. create function insert_datas2(in_start int(11),in_len int(11)) returns int(11) 
  24. begin   
  25.   declare cur_len int(11) default 0; 
  26.   declare cur_id int(11); 
  27.   set cur_id = in_start; 
  28.   
  29.   while cur_len < in_len do 
  30.      insert into t2 values(cur_id,cur_id,'北京'); 
  31.   set cur_len = cur_len + 1; 
  32.   set cur_id = cur_id + 1; 
  33.   end while;  
  34.   return cur_len; 
  35. end   
  36. // 
  37. delimiter ; 

在此之前,先清空表里的數(shù)據(jù),然后執(zhí)行函數(shù),

  1. select insert_datas1(1,1000000); 

對 t2 做同樣的處理,不過為了兩張表數(shù)據(jù)有交叉,就從 70W 開始,然后插入 200W 數(shù)據(jù)。

  1. select insert_datas2(700000,2000000); 

在家里的電腦,實際執(zhí)行時間,分別為 36s 和 74s。

不知為何,家里的電腦還沒有在 Docker 虛擬機中跑的腳本快。。害,就這樣湊合著用吧。

等我有了新歡錢,就把它換掉,哼哼。

同樣的,把上邊的執(zhí)行計劃都執(zhí)行一遍,進行對比。我這里就不貼圖了。

in 和 exists 孰快孰慢

為了方便,主要拿以下這兩個 sql 來對比分析。

  1. select * from t1 where id in (select id from t2); 
  2. select * from t1 where exists (select 1 from t2 where t1.id=t2.id); 

執(zhí)行結(jié)果顯示,兩個 sql 分別執(zhí)行 1.3s 和 3.4s 。

注意此時,t1 表數(shù)據(jù)量為 100W, t2 表數(shù)據(jù)量為 200W 。

按照網(wǎng)上對 in 和 exists 區(qū)別的通俗說法,

如果查詢的兩個表大小相當(dāng),那么用in和exists差別不大;如果兩個表中一個較小一個較大,則子查詢表大的用exists,子查詢表小的用in;

對應(yīng)于此處就是:

  • 當(dāng) t1 為小表, t2 為大表時,應(yīng)該用 exists ,這樣效率高。
  • 當(dāng) t1 為大表,t2 為小表時,應(yīng)該用 in,這樣效率較高。

而我用實際數(shù)據(jù)測試,就把第一種說法給推翻了。因為很明顯,t1 是小表,但是 in 比 exists 的執(zhí)行速度還快。

為了繼續(xù)測驗它這個觀點,我把兩個表的內(nèi)表外表關(guān)系調(diào)換一下,讓 t2 大表作為外表,來對比查詢,

  1. select * from t2 where id in (select id from t1); 
  2. select * from t2 where exists (select 1 from t1 where t1.id=t2.id); 

執(zhí)行結(jié)果顯示,兩個 sql 分別執(zhí)行 1.8s 和 10.0s 。

是不是很有意思。可以發(fā)現(xiàn),

  • 對于 in 來說,大表小表調(diào)換了內(nèi)外層關(guān)系,執(zhí)行時間并無太大區(qū)別。一個是 1.3s,一個是 1.8s。
  • 對于 exists 來說,大小表調(diào)換了內(nèi)外層關(guān)系,執(zhí)行時間天壤之別,一個是 3.4s ,一個是 10.0s,足足慢了兩倍。

一、以查詢優(yōu)化器維度對比。

為了探究這個結(jié)果的原因。我去查看它們分別在查詢優(yōu)化器中優(yōu)化后的 sql 。

  1. -- 此為 5.7 寫法,如果是 5.6版本,需要用 explain extended ... 
  2. explain select * from t1 where id in (select id from t2); 
  3. -- 本意為顯示警告信息。但是和 explain 一塊兒使用,就會顯示出優(yōu)化后的sql。需要注意使用順序。 
  4. show warnings; 

-- 此為 5.7 寫法,如果是 5.6版本,需要用 explain extended ...explain select * from t1 where id in (select id from t2);-- 本意為顯示警告信息。但是和 explain 一塊兒使用,就會顯示出優(yōu)化后的sql。需要注意使用順序。show warnings;

在結(jié)果 Message 里邊就會顯示我們要的語句。

  1. -- message 優(yōu)化后的sql 
  2. select `test`.`t1`.`id` AS `id`,`test`.`t1`.`nameAS `name`,`test`.`t1`.`address` AS `address` from `test`.`t2` join `test`.`t1` where (`test`.`t2`.`id` = `test`.`t1`.`id`) 

可以發(fā)現(xiàn),這里它把 in 轉(zhuǎn)換為了 join 來執(zhí)行。

這里沒有用 on,而用了 where,是因為當(dāng)只有 join 時,后邊的 on 可以用 where 來代替。即 join on 等價于 join where 。

PS: 這里我們也可以發(fā)現(xiàn),select * 最終會被轉(zhuǎn)化為具體的字段,知道為什么我們不建議用 select * 了吧。

同樣的,以 t2 大表為外表的查詢情況,也查看優(yōu)化后的語句。

  1. explain select * from t2 where id in (select id from t1); 
  2. show warnings; 

我們會發(fā)現(xiàn),它也會轉(zhuǎn)化為 join 的。

  1. select `test`.`t2`.`id` AS `id`,`test`.`t2`.`nameAS `name`,`test`.`t2`.`address` AS `address` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`id` = `test`.`t1`.`id`) 

這里不再貼 exists 的轉(zhuǎn)化 sql ,其實它沒有什么大的變化。

二、以執(zhí)行計劃維度對比。

我們再以執(zhí)行計劃維度來對比他們的區(qū)別。

  1. explain select * from t1 where id in (select id from t2); 
  2. explain select * from t2 where id in (select id from t1); 
  3. explain select * from t1 where exists (select 1 from t2 where t1.id=t2.id); 
  4. explain select * from t2 where exists (select 1 from t1 where t1.id=t2.id); 

執(zhí)行結(jié)果分別為,

1

2

3


 

4

 

可以發(fā)現(xiàn),對于 in 來說,大表 t2 做外表還是內(nèi)表,都會走索引的,小表 t1 做內(nèi)表時也會走索引。看它們的 rows 一列也可以看出來,前兩張圖結(jié)果一樣。

對于 exists 來說,當(dāng)小表 t1 做外表時,t1 全表掃描,rows 近 100W;當(dāng) 大表 t2 做外表時, t2 全表掃描,rows 近 200W 。這也是為什么 t2 做外表時,執(zhí)行效率非常低的原因。

因為對于 exists 來說,外表總會執(zhí)行全表掃描的,當(dāng)然表數(shù)據(jù)越少越好了。

最終結(jié)論: 外層大表內(nèi)層小表,用in。外層小表內(nèi)層大表,in和exists效率差不多(甚至 in 比 exists 還快,而并不是網(wǎng)上說的 exists 比 in 效率高)。

not in 和 not exists 孰快孰慢

此外,實測對比 not in 和 not exists 。

  1. explain select * from t1 where id not in (select id from t2); 
  2. explain select * from t1 where not exists (select 1 from t2 where t1.id=t2.id); 
  3. explain select * from t1 where name not in (select name from t2); 
  4. explain select * from t1 where not exists (select 1 from t2 where t1.name=t2.name); 
  5.  
  6. explain select * from t2 where id not in (select id from t1); 
  7. explain select * from t2 where not exists (select 1 from t1 where t1.id=t2.id); 
  8. explain select * from t2 where name not in (select name from t1); 
  9. explain select * from t2 where not exists (select 1 from t1 where t1.name=t2.name); 

小表做外表的情況下。對于主鍵來說, not exists 比 not in 快。對于普通索引來說, not in 和 not exists 差不了多少,甚至 not in 會稍快。

大表做外表的情況下,對于主鍵來說, not in 比 not exists 快。對于普通索引來說, not in 和 not exists 差不了多少,甚至 not in 會稍快。

感興趣的同學(xué),可自行嘗試。以上邊的兩個維度(查詢優(yōu)化器和執(zhí)行計劃)分別來對比一下。

join 的嵌套循環(huán) (Nested-Loop Join)

為了理解為什么這里的 in 會轉(zhuǎn)換為 join ,我感覺有必要了解一下 join 的三種嵌套循環(huán)連接。

1、簡單嵌套循環(huán)連接,Simple Nested-Loop Join ,簡稱 SNLJ

join 即是 inner join ,內(nèi)連接,它是一個笛卡爾積,即利用雙層循環(huán)遍歷兩張表。

我們知道,一般在 sql 中都會以小表作為驅(qū)動表。所以,對于 A,B 兩張表,若A的結(jié)果集較少,則把它放在外層循環(huán),作為驅(qū)動表。自然,B 就在內(nèi)層循環(huán),作為被驅(qū)動表。

簡單嵌套循環(huán),就是最簡單的一種情況,沒有做任何優(yōu)化。

因此,復(fù)雜度也是最高的,O(mn)。偽代碼如下,

  1. for(id1 in A){ 
  2.     for(id2 in B){ 
  3.         if(id1==id2){ 
  4.             result.add(); 
  5.         } 
  6.     } 

2、索引嵌套循環(huán)連接,Index Nested-Loop Join ,簡稱 INLJ

看名字也能看出來了,這是通過索引進行匹配的。外層表直接和內(nèi)層表的索引進行匹配,這樣就不需要遍歷整個內(nèi)層表了。利用索引,減少了外層表和內(nèi)層表的匹配次數(shù)。

所以,此種情況要求內(nèi)層表的列要有索引。

偽代碼如下,

  1. for(id1 in A){ 
  2.     if(id1 matched B.id){ 
  3.         result.add(); 
  4.     } 

3、塊索引嵌套連接,Block Nested-Loop Join ,簡稱 BNLJ

塊索引嵌套連接,是通過緩存外層表的數(shù)據(jù)到 join buffer 中,然后 buffer 中的數(shù)據(jù)批量和內(nèi)層表數(shù)據(jù)進行匹配,從而減少內(nèi)層循環(huán)的次數(shù)。

以外層循環(huán)100次為例,正常情況下需要在內(nèi)層循環(huán)讀取外層數(shù)據(jù)100次。如果以每10條數(shù)據(jù)存入緩存buffer中,并傳遞給內(nèi)層循環(huán),則內(nèi)層循環(huán)只需要讀取10次(100/10)就可以了。這樣就降低了內(nèi)層循環(huán)的讀取次數(shù)。

MySQL 官方文檔也有相關(guān)說明,可以參考:https://dev.mysql.com/doc/refman/5.7/en/nested-loop-joins.html#block-nested-loop-join-algorithm

 

所以,這里轉(zhuǎn)化為 join,可以用到索引嵌套循環(huán)連接,從而提高了執(zhí)行效率。

本文轉(zhuǎn)載自微信公眾號「煙雨星空」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系煙雨星空公眾號。

 

責(zé)任編輯:武曉燕 來源: 煙雨星空
相關(guān)推薦

2022-03-14 10:14:43

底層系統(tǒng)Nacos

2020-12-11 09:24:19

Elasticsear存儲數(shù)據(jù)

2018-09-28 05:25:53

TopK算法代碼

2018-11-09 09:34:05

面試Spring Clou底層

2019-08-29 09:49:50

2020-09-24 14:40:55

Python 開發(fā)編程語言

2020-04-22 11:19:07

貪心算法動態(tài)規(guī)劃

2018-11-01 13:49:23

桶排序排序面試

2018-10-28 22:37:00

計數(shù)排序排序面試

2021-01-22 10:09:23

簡歷求職者面試

2020-04-16 08:22:11

HTTPS加解密協(xié)議

2015-02-13 10:42:31

前端工具Dreamweaver

2021-11-24 10:10:32

axios前端攔截器

2024-11-29 10:44:00

2020-03-30 17:20:54

B+樹SQL索引

2020-04-02 11:06:47

數(shù)據(jù)庫Docker容器

2022-02-24 07:48:47

MySQL索引查詢

2019-12-17 09:29:02

數(shù)據(jù)庫架構(gòu)分庫分表

2021-09-29 07:29:57

索引子查詢開發(fā)

2018-11-06 11:40:19

時間復(fù)雜度面試算法
點贊
收藏

51CTO技術(shù)棧公眾號

深夜福利在线观看直播| 亚洲色图久久久| 亚洲欧美高清视频| 国产美女诱惑一区二区| 日韩中文字幕久久| 成人区人妻精品一区二| 成人在线免费av| 一级日本不卡的影视| 欧美一区观看| 成人综合电影| 国产女主播喷水高潮网红在线| 日本午夜免费一区二区| 无吗不卡中文字幕| 欧美aaa在线观看| 可以在线观看的av网站| 国产凹凸在线观看一区二区| 国产精品第3页| 中文在线观看免费网站| 天天影视综合| 亚洲色图第一页| 中文字幕乱码一区| 国产精品一区二区三区四区在线观看 | 国产精品久久久久秋霞鲁丝 | 国产成人亚洲欧美| 日韩黄色一级视频| 国产欧美91| 欧美国产日韩xxxxx| 色www亚洲国产阿娇yao| 自拍视频一区| 亚洲精品按摩视频| 好吊操视频这里只有精品| 91成人在线网站| 欧美丝袜自拍制服另类| 92看片淫黄大片一级| 91高清视频在线观看| 亚洲免费视频成人| 一本二本三本亚洲码| 超碰免费97在线观看| 91视频免费看| 香蕉亚洲视频| 精品国内亚洲在观看18黄| 蜜桃无码一区二区三区| 免费看成人人体视频| 欧美va亚洲va| 男男受被啪到高潮自述| 在线高清欧美| 制服视频三区第一页精品| 久草福利视频在线| 国产精品亚洲lv粉色| 麻豆成人精品| 欧美在线免费视频| 51精品国产人成在线观看| 波多野结衣家庭主妇| 欧美亚洲一级| 国产成人精品久久| 久久久久久在线观看| 亚洲女人av| 性视频1819p久久| 日韩av在线播| 99精品视频免费| 欧美亚洲一级片| av网站中文字幕| 久久午夜激情| 国产精品一区二区久久久| 成人黄色三级视频| 中文字幕亚洲综合久久| 5月婷婷6月丁香| 手机在线观看av网站| 五月婷婷综合在线| 免费无码av片在线观看| 蜜臀国产一区| 欧美色区777第一页| 天天干天天玩天天操| 国产小视频在线观看免费| 欧美黄色大片在线观看| 久久亚洲综合国产精品99麻豆精品福利| 日韩国产第一页| 欧美黄色免费| 91精品国产亚洲| 国产一级片免费视频| 麻豆精品蜜桃视频网站| 91影视免费在线观看| 人妻精品一区二区三区| 91蜜桃在线免费视频| 日韩精品电影网站| 免费不卡视频| 亚洲一区二区三区四区在线免费观看 | 国产又黄又粗又硬| 国产aⅴ精品一区二区三区色成熟| 国产一区在线免费| 国产女人在线视频| 亚洲精品伦理在线| 女性女同性aⅴ免费观女性恋| 校园春色亚洲色图| 91精品国产丝袜白色高跟鞋| 日本一区二区在线观看视频| 中文字幕理论片| 韩国一区二区三区视频| 日韩福利视频在线观看| 黄色精品视频在线观看| 在线亚洲激情| 亚洲最大成人在线| 国产在线观看免费| 玉足女爽爽91| 污污的网站18| 久久丝袜视频| 欧美插天视频在线播放| 男人天堂2024| 成人午夜电影网站| 一区二区三区av| 中文字幕影音在线| 日韩欧美激情一区| 午夜国产福利视频| 亚洲欧美卡通另类91av| www.成人三级视频| 午夜激情视频在线| 一本到不卡精品视频在线观看| 欧美污在线观看| 日韩国产一区二区| 538国产精品视频一区二区| www.天堂av.com| 国产精品毛片大码女人| 国产成人a亚洲精v品无码| 视频精品国内| 日韩在线资源网| 好看的日韩精品视频在线| 在线播放精品视频| 久久蜜桃av一区精品变态类天堂| h无码动漫在线观看| 一区二区三区无毛| 在线精品播放av| www.国产毛片| 久久综合九色综合欧美亚洲| 超碰成人免费在线| 亚洲成人影音| 欧美另类交人妖| 国产成人精品无码高潮| 1024成人网| www.超碰97.com| 都市激情国产精品| 日韩免费在线观看| 91 在线视频| 捆绑调教美女网站视频一区| 秋霞毛片久久久久久久久| 男人av在线播放| 亚洲精品720p| 久久人体av| 欧美三级特黄| 91在线免费看网站| 亚洲精品传媒| 欧美日韩精品一区二区三区蜜桃| 欧美人妻一区二区| 国产一区二区三区电影在线观看| 97在线免费视频| 亚洲国产精品国自产拍久久| 亚洲精选视频免费看| 国产黄色一区二区| 久久综合99re88久久爱| 国产精品-区区久久久狼| 国产高潮失禁喷水爽到抽搐| 久久天堂av| 视频在线观看一区二区| 中文字幕一区二区三区人妻四季| 国产精品无人区| 亚洲精品免费一区亚洲精品免费精品一区 | 日本在线观看www| 欧美日韩精品系列| 2025国产精品自拍| 丁香五精品蜜臀久久久久99网站| 九九爱精品视频| 亚洲精品进入| 国产精品美女久久久久久免费 | 57pao精品| 触手亚洲一区二区三区| 视频精品一区| 日韩视频―中文字幕| 性猛交富婆╳xxx乱大交天津| 亚洲成人午夜影院| 免费一级做a爰片久久毛片潮| 美日韩一区二区| 亚洲精品天堂成人片av在线播放| 九色丨蝌蚪丨成人| 国产精品第七十二页| 99福利在线| 日韩精品极品在线观看播放免费视频| 无码久久精品国产亚洲av影片| 中文字幕日韩av资源站| 亚洲天堂美女视频| 蜜臀av性久久久久av蜜臀妖精| 欧美激情亚洲天堂| 狠狠做六月爱婷婷综合aⅴ | 国产欧美日韩三区| 污污的视频免费观看| 一本久道久久综合狠狠爱| 亚洲欧美日韩精品在线| 99re8这里有精品热视频8在线| 欧美孕妇毛茸茸xxxx| 免费a级毛片在线播放| 亚洲韩国欧洲国产日产av| 中文天堂在线播放| 午夜视频久久久久久| 成人18视频免费69| 91色porny| 深爱五月综合网| 天使萌一区二区三区免费观看| 法国空姐在线观看免费| 国产精品一区二区av日韩在线| www.成人三级视频| 欧美男男gaygay1069| 日本成人在线视频网址| 在线中文字幕-区二区三区四区 | 亚洲区欧洲区| 色诱女教师一区二区三区| 少妇人妻精品一区二区三区| 欧美一级二级在线观看| 免费黄色小视频在线观看| 亚洲福利一区二区三区| 99久久婷婷国产综合| 国产视频一区在线播放| 久久福利小视频| 国产成人免费视频网站高清观看视频| 久久久国产一区二区| 日韩精品国产一区二区| 亚洲免费高清视频在线| 中国美女黄色一级片| 久久久精品国产免费观看同学| 精品久久久久久无码人妻| 激情欧美一区二区三区在线观看| www.xxx亚洲| 老牛嫩草一区二区三区日本| 大肉大捧一进一出好爽视频| 狠狠88综合久久久久综合网| 99精品一区二区三区的区别| 日本成人小视频| 日韩精品在在线一区二区中文| 亚洲激情播播| 久久亚洲一区二区| 香蕉精品久久| 欧美二级三级| 伊人成综合网yiren22| 欧美大香线蕉线伊人久久| 欧美国产极品| 久久精品国产99精品国产亚洲性色| 99久久免费精品国产72精品九九| 91嫩草免费看| 影音先锋久久| 欧美在线免费看| 岛国av在线播放| 欧美精品18videosex性欧美| 羞羞的视频在线看| 欧美成人免费网| 最新av在线播放| 欧美成人精品xxx| 麻豆影视在线播放| 黄色免费看视频| 日本vs亚洲vs韩国一区三区二区| 能在线观看的av| 老鸭窝毛片一区二区三区| 国产日产欧美视频| 玖玖玖国产精品| 成年网站在线播放| 久久99国产精品久久99| 伦伦影院午夜理论片| 国产成人午夜电影网| 欧洲熟妇的性久久久久久| 成人动漫在线一区| 777电影在线观看| 欧美日韩一区二区三区在线| 中日韩av在线| 欧美顶级少妇做爰| 亚洲春色一区二区三区| 亚洲精品99久久久久中文字幕| 色鬼7777久久| 在线观看视频亚洲| 伊人影院在线视频| 57pao成人永久免费视频| 91九色丨porny丨国产jk| 精品久久视频| 免费观看中文字幕| 91久久综合| 欧美伦理片在线看| 国产一区二区调教| 香港三级日本三级| 中文字幕在线观看不卡| 国产一级视频在线| 91久久免费观看| 国产成人三级一区二区在线观看一| 精品日产卡一卡二卡麻豆| av视屏在线播放| 午夜福利视频一区二区| 中文字幕在线播放不卡一区| 91视频免费在线看| 日韩欧美极品在线观看| 91精品国产乱码久久久久| 亚洲精品国产福利| 亚洲精品日韩激情在线电影| av综合网页| 伊人久久大香线蕉av一区| 亚洲精品1区| 狠狠干狠狠操视频| 91网站在线播放| 99久久婷婷国产综合| 一本色道a无线码一区v| 精品国自产拍在线观看| 伊人青青综合网站| 欧美hdxxx| 国产欧美va欧美va香蕉在| 另类在线视频| 女同性恋一区二区| 日本成人在线电影网| 成人在线视频免费播放| 亚洲色图视频免费播放| 日本久久综合网| 欧美精品一区二区三区视频| 国内精品久久久久国产| 国产91精品最新在线播放| 久久久久久毛片免费看 | 亚洲成国产人片在线观看| 一级黄色大片免费观看| 亚洲欧洲激情在线| av日韩中文| 99国产在线观看| 91精品一区二区三区综合在线爱| 成人性视频欧美一区二区三区| 99久久777色| xxxxxx国产| 日韩视频免费观看高清完整版| 丝袜美腿美女被狂躁在线观看| 国产成人精品久久久| 美日韩黄色大片| 日韩a级在线观看| 懂色av一区二区三区免费看| 亚洲视频一二三四| 国产精品久久福利| 中文字幕av在线免费观看| 亚洲美女在线观看| 日本不卡网站| 久久久久九九九| 国产视频久久| 性欧美丰满熟妇xxxx性久久久| 亚洲成人www| 亚洲国产精品久久久久久6q| 欧美激情亚洲一区| 在线播放一区二区精品视频| 免费极品av一视觉盛宴| 国产精品一区二区免费不卡| 日韩va亚洲va欧美va清高| 日韩一区二区三区高清免费看看| 国产精品久久久久久福利| 国产精品亚洲欧美导航| 99国产精品免费视频观看| 99中文字幕在线| 亚洲精品免费在线播放| 亚洲精品911| 91国产视频在线播放| 久久综合欧美| 亚欧激情乱码久久久久久久久| 亚洲欧洲精品天堂一级| 国产乱码精品一区二区三区精东| 美女福利视频一区| 国产欧美一区二区三区视频在线观看| 成人h精品动漫一区二区三区| 久久久久成人精品无码| 精品国产sm最大网站免费看| 国产不卡人人| 欧美亚洲免费高清在线观看| 免费观看一级特黄欧美大片| 国产3级在线观看| 日韩精品一区二区在线| www成人免费观看| 欧美深深色噜噜狠狠yyy| 麻豆精品在线视频| 91成人福利视频| 亚洲高清一区二| 一二区成人影院电影网| 欧美一区二区在线视频观看| av午夜在线观看| 日韩经典中文字幕| 日本免费中文字幕在线| 日韩中文字幕av| 成人在线视频国产| 18黄暴禁片在线观看| 91麻豆精品在线观看| 制服丝袜在线一区| 另类专区欧美制服同性| 国产66精品| 中文字幕天天干| 亚洲一区二区综合| 国产一区二区影视| 亚洲最大的网站| 裸体xxxx视频在线| 日本成人在线视频网址| 色喇叭免费久久综合网| 美女露出粉嫩尿囗让男人桶| 一本久道中文字幕精品亚洲嫩| av在线免费网址| 日本亚洲自拍| 成人午夜精品在线| 亚洲一区二区三区高清视频| 97视频在线观看成人|