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

歡迎訪問 生活随笔!

生活随笔

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

数据库

Day517.索引优化与查询优化 -mysql

發布時間:2024/3/26 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Day517.索引优化与查询优化 -mysql 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

索引優化與查詢優化

一、數據準備

學員表 插 50萬 條, 班級表 插 1萬 條。

步驟1:建表

#班級表 CREATE TABLE `class` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `className` VARCHAR(30) DEFAULT NULL, `address` VARCHAR(40) DEFAULT NULL, `monitor` INT NULL , PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;#學員表 CREATE TABLE `student` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `stuno` INT NOT NULL , `name` VARCHAR(20) DEFAULT NULL, `age` INT(3) DEFAULT NULL, `classId` INT(11) DEFAULT NULL, PRIMARY KEY (`id`) #CONSTRAINT `fk_class_id` FOREIGN KEY (`classId`) REFERENCES `t_class` (`id`) ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

步驟2:設置參數

命令開啟:允許創建函數設置:

set global log_bin_trust_function_creators=1; # 不加global只是當前窗口有效。

步驟3:創建函數

保證每條數據都不同。

#隨機產生字符串 DELIMITER // CREATE FUNCTION rand_string(n INT) RETURNS VARCHAR(255) BEGIN DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'; DECLARE return_str VARCHAR(255) DEFAULT ''; DECLARE i INT DEFAULT 0; WHILE i < n DO SET return_str =CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1)); SET i = i + 1; END WHILE; RETURN return_str; END // DELIMITER ;#假如要刪除 #drop function rand_string;

隨機產生班級編號

#用于隨機產生多少到多少的編號 DELIMITER // CREATE FUNCTION rand_num (from_num INT ,to_num INT) RETURNS INT(11) BEGIN DECLARE i INT DEFAULT 0; SET i = FLOOR(from_num +RAND()*(to_num - from_num+1)) ; RETURN i; END // DELIMITER ;#假如要刪除 #drop function rand_num;

步驟4:創建存儲過程

#創建往stu表中插入數據的存儲過程 DELIMITER // CREATE PROCEDURE insert_stu( START INT , max_num INT ) BEGIN DECLARE i INT DEFAULT 0; SET autocommit = 0; #設置手動提交事務REPEAT #循環SET i = i + 1; #賦值INSERT INTO student (stuno, name ,age ,classId ) VALUES((START+i),rand_string(6),rand_num(1,50),rand_num(1,1000)); UNTIL i = max_num END REPEAT; COMMIT; #提交事務 END // DELIMITER ;#假如要刪除 #drop PROCEDURE insert_stu;

創建往class表中插入數據的存儲過程

#執行存儲過程,往class表添加隨機數據 DELIMITER // CREATE PROCEDURE `insert_class`( max_num INT ) BEGIN DECLARE i INT DEFAULT 0; SET autocommit = 0; REPEAT SET i = i + 1; INSERT INTO class ( classname,address,monitor ) VALUES(rand_string(8),rand_string(10),rand_num(1,100000)); UNTIL i = max_num END REPEAT; COMMIT; END // DELIMITER ;#假如要刪除 #drop PROCEDURE insert_class;

步驟5:調用存儲過程
class

#執行存儲過程,往class表添加1萬條數據 CALL insert_class(10000);

stu

#執行存儲過程,往stu表添加50萬條數據 CALL insert_stu(100000,500000);

步驟6:刪除某表上的索引
創建存儲過程

DELIMITER // CREATE PROCEDURE `proc_drop_index`(dbname VARCHAR(200),tablename VARCHAR(200)) BEGINDECLARE done INT DEFAULT 0;DECLARE ct INT DEFAULT 0;DECLARE _index VARCHAR(200) DEFAULT '';DECLARE _cur CURSOR FOR SELECT index_name FROM information_schema.STATISTICS WHERE table_schema=dbname AND table_name=tablename AND seq_in_index=1 AND index_name <>'PRIMARY' ; #每個游標必須使用不同的declare continue handler for not found set done=1來控制游標的結束DECLARE CONTINUE HANDLER FOR NOT FOUND set done=2 ; #若沒有數據返回,程序繼續,并將變量done設為2OPEN _cur;FETCH _cur INTO _index;WHILE _index<>'' DOSET @str = CONCAT("drop index " , _index , " on " , tablename );PREPARE sql_str FROM @str ;EXECUTE sql_str;DEALLOCATE PREPARE sql_str;SET _index='';FETCH _cur INTO _index;END WHILE;CLOSE _cur; END // DELIMITER ;

執行存儲過程

CALL proc_drop_index("dbname","tablename");

二、索引失效案例

1、全值匹配我最愛

全值的等值匹配

2、最佳左前綴法則

拓展:Alibaba《Java開發手冊》
索引文件具有 B-Tree 的最左前綴匹配特性,如果左邊的值未確定,那么無法使用此索引。

3、主鍵插入順序


如果此時再插入一條主鍵值為 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 屬性,在插入記錄時存儲引擎會自動為我們填入自增的主鍵值。這樣的主鍵占用空間小,順序寫入,減少頁分裂。

4、計算、函數、類型轉換(自動或手動)導致索引失效

EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE student.name LIKE 'abc%'; EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE LEFT(student.name,3) = 'abc';

創建索引

CREATE INDEX idx_name ON student(NAME);

第一種:索引優化生效

mysql> EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE student.name LIKE 'abc%'; mysql> SELECT SQL_NO_CACHE * FROM student WHERE student.name LIKE 'abc%'; +---------+---------+--------+------+---------+ | id | stuno | name | age | classId | +---------+---------+--------+------+---------+ | 5301379 | 1233401 | AbCHEa | 164 | 259 | | 7170042 | 3102064 | ABcHeB | 199 | 161 | | 1901614 | 1833636 | ABcHeC | 226 | 275 | | 5195021 | 1127043 | abchEC | 486 | 72 | | 4047089 | 3810031 | AbCHFd | 268 | 210 | | 4917074 | 849096 | ABcHfD | 264 | 442 | | 1540859 | 141979 | abchFF | 119 | 140 | | 5121801 | 1053823 | AbCHFg | 412 | 327 | | 2441254 | 2373276 | abchFJ | 170 | 362 | | 7039146 | 2971168 | ABcHgI | 502 | 465 | | 1636826 | 1580286 | ABcHgK | 71 | 262 | | 374344 | 474345 | abchHL | 367 | 212 | | 1596534 | 169191 | AbCHHl | 102 | 146 |... | 5266837 | 1198859 | abclXe | 292 | 298 | | 8126968 | 4058990 | aBClxE | 316 | 150 | | 4298305 | 399962 | AbCLXF | 72 | 423 | | 5813628 | 1745650 | aBClxF | 356 | 323 | | 6980448 | 2912470 | AbCLXF | 107 | 78 | | 7881979 | 3814001 | AbCLXF | 89 | 497 | | 4955576 | 887598 | ABcLxg | 121 | 385 | | 3653460 | 3585482 | AbCLXJ | 130 | 174 | | 1231990 | 1283439 | AbCLYH | 189 | 429 | | 6110615 | 2042637 | ABcLyh | 157 | 40 | +---------+---------+--------+------+---------+ 401 rows in set, 1 warning (0.01 sec)

第二種:索引優化失效

mysql> EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE LEFT(student.name,3) = 'abc';

mysql> SELECT SQL_NO_CACHE * FROM student WHERE LEFT(student.name,3) = 'abc'; +---------+---------+--------+------+---------+ | id | stuno | name | age | classId | +---------+---------+--------+------+---------+ | 5301379 | 1233401 | AbCHEa | 164 | 259 | | 7170042 | 3102064 | ABcHeB | 199 | 161 | | 1901614 | 1833636 | ABcHeC | 226 | 275 | | 5195021 | 1127043 | abchEC | 486 | 72 | | 4047089 | 3810031 | AbCHFd | 268 | 210 | | 4917074 | 849096 | ABcHfD | 264 | 442 | | 1540859 | 141979 | abchFF | 119 | 140 | | 5121801 | 1053823 | AbCHFg | 412 | 327 | | 2441254 | 2373276 | abchFJ | 170 | 362 | | 7039146 | 2971168 | ABcHgI | 502 | 465 | | 1636826 | 1580286 | ABcHgK | 71 | 262 | | 374344 | 474345 | abchHL | 367 | 212 | | 1596534 | 169191 | AbCHHl | 102 | 146 |... | 5266837 | 1198859 | abclXe | 292 | 298 | | 8126968 | 4058990 | aBClxE | 316 | 150 | | 4298305 | 399962 | AbCLXF | 72 | 423 | | 5813628 | 1745650 | aBClxF | 356 | 323 | | 6980448 | 2912470 | AbCLXF | 107 | 78 | | 7881979 | 3814001 | AbCLXF | 89 | 497 | | 4955576 | 887598 | ABcLxg | 121 | 385 | | 3653460 | 3585482 | AbCLXJ | 130 | 174 | | 1231990 | 1283439 | AbCLYH | 189 | 429 | | 6110615 | 2042637 | ABcLyh | 157 | 40 | +---------+---------+--------+------+---------+ 401 rows in set, 1 warning (3.62 sec)

type為“ALL”,表示沒有使用到索引,查詢時間為 3.62秒,查詢效率較之前低很多。

再舉例:

  • student表的字段stuno上設置有索引
CREATE INDEX idx_sno ON student(stuno); EXPLAIN SELECT SQL_NO_CACHE id, stuno, NAME FROM student WHERE stuno+1 = 900001;

  • 索引優化生效:
EXPLAIN SELECT SQL_NO_CACHE id, stuno, NAME FROM student WHERE stuno = 900000;

再舉例:

  • student表的字段name上設置有索引
CREATE INDEX idx_name ON student(NAME); EXPLAIN SELECT id, stuno, name FROM student WHERE SUBSTRING(name, 1,3)='abc';

EXPLAIN SELECT id, stuno, NAME FROM student WHERE NAME LIKE 'abc%';


5、類型轉換導致索引失效

下列哪個sql語句可以用到索引。(假設name字段上設置有索引)

# 未使用到索引 EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE name=123;

# 使用到索引 EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE name='123';


name=123發生類型轉換,索引失效。(隱式的類型轉換)


6、范圍條件右邊的列索引失效

ALTER TABLE student DROP INDEX idx_name; ALTER TABLE student DROP INDEX idx_age; ALTER TABLE student DROP INDEX idx_age_classid; EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE student.age=30 AND student.classId>20 AND student.name = 'abc' ; # student.classId>20的右側的student.name = 'abc'的索引就會失效

create index idx_age_name_classid on student(age,name,classid);
  • 將范圍查詢條件放置語句最后:
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE student.age=30 AND student.name = 'abc' AND student.classId>20 ; #直接交換sql語句的位置是沒有用的,需要改變聯合索引的位置

7、 不等于(!= 或者<>)索引失效

當sql語句中有!=或者<>會出現索引失效的問題,嘗試改寫為等于,或采用覆蓋索引

8、is null可以使用索引,is not null無法使用索引

EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE age IS NULL; EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE age IS NOT NULL;

9、 like以通配符%開頭索引失效

拓展:Alibaba《Java開發手冊》
【強制】頁面搜索嚴禁左模糊或者全模糊,如果需要請走搜索引擎來解決。

10、OR 前后存在非索引的列,索引失效

讓OR的前后條件都具備索引,如果缺少一個就會出現索引失效

# 未使用到索引 EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE age = 10 OR classid = 100;

#使用到索引 EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE age = 10 OR name = 'Abel';

11、數據庫和表的字符集統一使用utf8mb4

統一使用utf8mb4( 5.5.3版本以上支持)兼容性更好,統一字符集可以避免由于字符集轉換產生的亂碼。不同的 字符集 進行比較前需要進行 轉換 會造成索引失效。


三、關聯查詢優化

1、數據準備

2、采用左外連接

EXPLAIN SELECT SQL_NO_CACHE * FROM `type` LEFT JOIN book ON type.card = book.card;


結論:type 有All

添加索引優化

ALTER TABLE book ADD INDEX Y ( card); #【被驅動表】,可以避免全表掃描 EXPLAIN SELECT SQL_NO_CACHE * FROM `type` LEFT JOIN book ON type.card = book.card;


可以看到第二行的 type 變為了 ref,rows 也變成了優化比較明顯。這是由左連接特性決定的。
左外連接LEFT JOIN條件用于確定如何從右表搜索行,左邊一定都有,所以 右邊是我們的關鍵點,一定需要建立索引。

ALTER TABLE `type` ADD INDEX X (card); #【驅動表】,無法避免全表掃描 EXPLAIN SELECT SQL_NO_CACHE * FROM `type` LEFT JOIN book ON type.card = book.card;


然后

DROP INDEX Y ON book; EXPLAIN SELECT SQL_NO_CACHE * FROM `type` LEFT JOIN book ON type.card = book.card;

3、采用內連接

drop index X on type; drop index Y on book;(如果已經刪除了可以不用再執行該操作)

換成 inner join(MySQL自動選擇驅動表)

EXPLAIN SELECT SQL_NO_CACHE * FROM type INNER JOIN book ON type.card=book.card;


添加索引優化

ALTER TABLE book ADD INDEX Y ( card);EXPLAIN SELECT SQL_NO_CACHE * FROM type INNER JOIN book ON type.card=book.card;

ALTER TABLE type ADD INDEX X (card);EXPLAIN SELECT SQL_NO_CACHE * FROM type INNER JOIN book ON type.card=book.card;

接著:

DROP INDEX X ON `type`;EXPLAIN SELECT SQL_NO_CACHE * FROM TYPE INNER JOIN book ON type.card=book.card;


接著:

ALTER TABLE `type` ADD INDEX X (card); EXPLAIN SELECT SQL_NO_CACHE * FROM `type` INNER JOIN book ON type.card=book.card;

4、join語句原理

  • Index Nested-Loop Join
EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 ON (t1.a=t2.a);

如果直接使用join語句,MySQL優化器可能會選擇表t1或t2作為驅動表,這樣會影響我們分析SQL語句的執行過程。

所以,為了便于分析執行過程中的性能問題,我改用 straight_join讓MySQL使用固定的連接方式執行查詢,這樣優化器只會按照我們指定的方式去join。在這個語句里,t1 是驅動表,t2是被驅動表。

可以看到,在這條語句里,被驅動表t2的字段a上有索引,join過程用上了這個索引,因此這個語句的執行流程是這樣的:

  • 從表t1中讀入一行數據 R;
  • 從數據行R中,取出a字段到表t2里去查找;
  • 取出表t2中滿足條件的行,跟R組成一行,作為結果集的一部分;
  • 重復執行步驟1到3,直到表t1的末尾循環結束。
  • 這個過程是先遍歷表t1,然后根據從表t1中取出的每行數據中的a值,去表t2中查找滿足條件的記錄。在形式上,這個過程就跟我們寫程序時的嵌套查詢類似,并且可以用上被驅動表的索引,所以我們稱之為“Index Nested-Loop Join”,簡稱NLJ。

    它對應的流程圖如下所示:

    在這個流程里:

  • 對驅動表t1做了全表掃描,這個過程需要掃描100行;
  • 而對于每一行R,根據a字段去表t2查找,走的是樹搜索過程。由于我們構造的數據都是一一對應的,因此每次的搜索過程都只掃描一行,也是總共掃描100行;
  • 所以,整個執行流程,總掃描行數是200。
  • 引申問題1:能不能使用join?

    引申問題2:怎么選擇驅動表?

    比如:
    N擴大1000倍的話,掃描行數就會擴大1000倍;而M擴大1000倍,掃描行數擴大不到10倍。

    兩個結論

  • 使用join語句,性能比強行拆成多個單表執行SQL語句的性能要好;
  • 如果使用join語句的話,需要讓小表做驅動表。
    • Simple Nested-Loop Join
    • Block Nested-Loop Join

    這個過程的流程圖如下:

    執行流程圖也就變成這樣:


    總結1:能不能使用xxx join語句?

    總結2:如果要使用join,應該選擇大表做驅動表還是選擇小表做驅動表?

    總結3:什么叫作“小表”?

    在決定哪個表做驅動表的時候,應該是兩個表按照各自的條件過濾,過濾完成之后,計算參與join的各個字段的總數據量,數據量小的那個表,就是“小表”,應該作為驅動表。

    5、小結

    • 保證被驅動表的JOIN字段已經創建了索引
    • 需要JOIN 的字段,數據類型保持絕對一致。
    • LEFT JOIN 時,選擇小表作為驅動表, 大表作為被驅動表 。減少外層循環的次數。
    • INNER JOIN 時,MySQL會自動將 小結果集的表選為驅動表 。選擇相信MySQL優化策略。
    • 能夠直接多表關聯的盡量直接關聯,不用子查詢。(減少查詢的趟數)
    • 不建議使用子查詢,建議將子查詢SQL拆開結合程序多次查詢,或使用 JOIN 來代替子查詢。
    • 衍生表建不了索引

    四、子查詢優化

    看看能不能將子查詢優化成內外連接查詢
    MySQL從4.1版本開始支持子查詢,使用子查詢可以進行SELECT語句的嵌套查詢,即一個SELECT查詢的結果作為另一個SELECT語句的條件。 子查詢可以一次性完成很多邏輯上需要多個步驟才能完成的SQL操作。

    子查詢是 MySQL 的一項重要的功能,可以幫助我們通過一個 SQL 語句實現比較復雜的查詢。但是,子查詢的執行效率不高。

    原因

    ① 執行子查詢時,MySQL需要為內層查詢語句的查詢結果建立一個臨時表 ,然后外層查詢語句從臨時表中查詢記錄。查詢完畢后,再 撤銷這些臨時表 。這樣會消耗過多的CPU和IO資源,產生大量的慢查詢。

    ② 子查詢的結果集存儲的臨時表,不論是內存臨時表還是磁盤臨時表都 不會存在索引 ,所以查詢性能會受到一定的影響。

    ③ 對于返回結果集比較大的子查詢,其對查詢性能的影響也就越大。

    在MySQL中,可以使用連接(JOIN)查詢來替代子查詢。
    連接查詢 不需要建立臨時表,其 速度比子查詢要快 ,如果查詢中使用索引的話,性能就會更好。

    結論
    盡量不要使用NOT IN 或者 NOT EXISTS,用LEFT JOIN xxx ON xx WHERE xx IS NULL替代


    五、排序優化

    1、排序優化

    問題
    在 WHERE 條件字段上加索引,但是為什么在 ORDER BY 字段上還要加索引呢?
    優化建議

  • SQL 中,可以在 WHERE 子句和 ORDER BY 子句中使用索引,目的是在 WHERE 子句中 避免全表掃描 ,在 ORDER BY 子句 避免使用 FileSort 排序 。當然,某些情況下全表掃描,或者 FileSort 排序不一定比索引慢。但總的來說,我們還是要避免,以提高查詢效率。
  • 盡量使用 Index 完成 ORDER BY 排序。如果 WHERE 和 ORDER BY 后面是相同的列就使用單索引列;如果不同就使用聯合索引。
  • 無法使用 Index 時,需要對 FileSort 方式進行調優。
  • INDEX a_b_c(a,b,c) order by 能使用索引最左前綴 - ORDER BY a - ORDER BY a,b - ORDER BY a,b,c - ORDER BY a DESC,b DESC,c DESC 如果WHERE使用索引的最左前綴定義為常量,則order by 能使用索引 - WHERE a = const ORDER BY b,c - WHERE a = const AND b = const ORDER BY c - WHERE a = const ORDER BY b,c - WHERE a = const AND b > const ORDER BY b,c 不能使用索引進行排序 - ORDER BY a ASC,b DESC,c DESC /* 排序不一致 */ - WHERE g = const ORDER BY b,c /*丟失a索引*/ - WHERE a = const ORDER BY c /*丟失b索引*/ - WHERE a = const ORDER BY a,d /*d不是索引的一部分*/ - WHERE a in (...) ORDER BY b,c /*對于排序來說,多個相等條件也是范圍查詢*/

    2、案例實戰

    ORDER BY子句,盡量使用Index方式排序,避免使用FileSort方式排序。

    執行案例前先清除student上的索引,只留主鍵:

    DROP INDEX idx_age ON student; DROP INDEX idx_age_classid_stuno ON student; DROP INDEX idx_age_classid_name ON student; #或者 call proc_drop_index('atguigudb2','student');

    場景:查詢年齡為30歲的,且學生編號小于101000的學生,按用戶名稱排序

    EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE age = 30 AND stuno <101000 ORDER BY NAME ;


    查詢結果如下:

    mysql> SELECT SQL_NO_CACHE * FROM student WHERE age = 30 AND stuno <101000 ORDER BY NAME; +---------+--------+--------+------+---------+ | id | stuno | name | age | classId | +---------+--------+--------+------+---------+ | 922 | 100923 | elTLXD | 30 | 249 | | 3723263 | 100412 | hKcjLb | 30 | 59 | | 3724152 | 100827 | iHLJmh | 30 | 387 | | 3724030 | 100776 | LgxWoD | 30 | 253 | | 30 | 100031 | LZMOIa | 30 | 97 | | 3722887 | 100237 | QzbJdx | 30 | 440 | | 609 | 100610 | vbRimN | 30 | 481 | | 139 | 100140 | ZqFbuR | 30 | 351 | +---------+--------+--------+------+---------+ 8 rows in set, 1 warning (3.16 sec)

    結論
    type 是 ALL,即最壞的情況。Extra 里還出現了 Using filesort,也是最壞的情況。優化是必須的。

    優化思路:

    方案一: 為了去掉filesort我們可以把索引建成

    #創建新索引 CREATE INDEX idx_age_name ON student(age,NAME);

    方案二: 盡量讓where的過濾條件和排序使用上索引
    建一個三個字段的組合索引:

    DROP INDEX idx_age_name ON student; CREATE INDEX idx_age_stuno_name ON student (age,stuno,NAME); EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE age = 30 AND stuno <101000 ORDER BY NAME ; mysql> SELECT SQL_NO_CACHE * FROM student-> WHERE age = 30 AND stuno <101000 ORDER BY NAME ; +-----+--------+--------+------+---------+ | id | stuno | name | age | classId | +-----+--------+--------+------+---------+ | 167 | 100168 | AClxEF | 30 | 319 | | 323 | 100324 | bwbTpQ | 30 | 654 | | 651 | 100652 | DRwIac | 30 | 997 | | 517 | 100518 | HNSYqJ | 30 | 256 | | 344 | 100345 | JuepiX | 30 | 329 | | 905 | 100906 | JuWALd | 30 | 892 | | 574 | 100575 | kbyqjX | 30 | 260 | | 703 | 100704 | KJbprS | 30 | 594 | | 723 | 100724 | OTdJkY | 30 | 236 | | 656 | 100657 | Pfgqmj | 30 | 600 | | 982 | 100983 | qywLqw | 30 | 837 | | 468 | 100469 | sLEKQW | 30 | 346 | | 988 | 100989 | UBYqJl | 30 | 457 | | 173 | 100174 | UltkTN | 30 | 830 | | 332 | 100333 | YjWiZw | 30 | 824 | +-----+--------+--------+------+---------+ 15 rows in set, 1 warning (0.00 sec)

    結果竟然有 filesort的 sql 運行速度,超過了已經優化掉 filesort的 sql,而且快了很多,幾乎一瞬間就出現了結果。

    結論

  • 兩個索引同時存在,mysql自動選擇最優的方案。(對于這個例子,mysql選擇
    idx_age_stuno_name)。但是, 隨著數據量的變化,選擇的索引也會隨之變化的 。
  • 當【范圍條件】和【group by 或者 order by】的字段出現二選一時,優先觀察條件字段的過濾數量,如果過濾的數據足夠多,而需要排序的數據并不多時,優先把索引放在范圍字段上。反之,亦然。
  • 思考:這里我們使用如下索引,是否可行?

    DROP INDEX idx_age_stuno_name ON student; CREATE INDEX idx_age_stuno ON student(age,stuno);

    4、filesort算法:雙路排序和單路排序

    雙路排序 (慢)

    • MySQL 4.1之前是使用雙路排序 ,字面意思就是兩次掃描磁盤,最終得到數據, 讀取行指針和order by列 ,對他們進行排序,然后掃描已經排序好的列表,按照列表中的值重新從列表中讀取對應的數據輸出
    • 從磁盤取排序字段,在buffer進行排序,再從 磁盤取其他字段 。

    取一批數據,要對磁盤進行兩次掃描,眾所周知,IO是很耗時的,所以在mysql4.1之后,出現了第二種改進的算法,就是單路排序。

    單路排序 (快)
    從磁盤讀取查詢需要的 所有列 ,按照order by列在buffer對它們進行排序,然后掃描排序后的列表進行輸出, 它的效率更快一些,避免了第二次讀取數據。并且把隨機IO變成了順序IO,但是它會使用更多的空
    間, 因為它把每一行都保存在內存中了。

    結論及引申出的問題

    • 由于單路是后出的,總體而言好過雙路
    • 但是用單路有問題

    優化策略

  • 嘗試提高 sort_buffer_size
  • 嘗試提高 max_length_for_sort_data
  • Order by 時select * 是一個大忌。最好只Query需要的字段。

  • 六、GROUP BY優化

    • group by 使用索引的原則幾乎跟order by一致 ,group by 即使沒有過濾條件用到索引,也可以直接使用索引。
    • group by 先排序再分組,遵照索引建的最佳左前綴法則
    • 當無法使用索引列,增大 max_length_for_sort_data 和 sort_buffer_size 參數的設置
    • where效率高于having,能寫在where限定的條件就不要寫在having中
    • 減少使用order by,和業務溝通能不排序就不排序,或將排序放到程序端去做。Order by、group by、distinct這些語句較為耗費CPU,數據庫的CPU資源是極其寶貴的。
    • 包含了order by、group by、distinct這些查詢的語句,where條件過濾出來的結果集請保持在1000行以內,否則SQL會很慢。

    七、優化分頁查詢

    優化思路一

    在索引上完成排序分頁操作,最后根據主鍵關聯回原表查詢所需要的其他列內容。

    EXPLAIN SELECT * FROM student t,(SELECT id FROM student ORDER BY id LIMIT 2000000,10) a WHERE t.id = a.id;


    優化思路二:

    該方案適用于主鍵自增的表,可以把Limit 查詢轉換成某個位置的查詢 。

    EXPLAIN SELECT * FROM student WHERE id > 2000000 LIMIT 10;

    八、優先考慮覆蓋索引

    1、什么是覆蓋索引?

    直接通過二級索引對應的數據找到了查詢結果,無需回表

    • 理解方式一:索引是高效找到行的一個方法,但是一般數據庫也能使用索引找到一個列的數據,因此它不必讀取整個行。畢竟索引葉子節點存儲了它們索引的數據;當能通過讀取索引就可以得到想要的數據,那就不需要讀取行了。一個索引包含了滿足查詢結果的數據就叫做覆蓋索引。

    • 理解方式二:非聚簇復合索引的一種形式,它包括在查詢里的SELECT、JOIN和WHERE子句用到的所有列(即建索引的字段正好是覆蓋查詢條件中所涉及的字段)。

    簡單說就是, 索引列+主鍵 包含 SELECT 到 FROM之間查詢的列 。

    2、覆蓋索引的利弊

    好處

  • 避免Innodb表進行索引的二次查詢(回表)
  • 可以把隨機IO變成順序IO加快查詢效率
  • 弊端
    索引字段的維護 總是有代價的。因此,在建立冗余索引來支持覆蓋索引時就需要權衡考慮了。這是業務DBA,或者稱為業務數據架構師的工作。


    九、如何給字符串添加索引

    有一張教師表,表定義如下:

    create table teacher(ID bigint unsigned primary key,email varchar(64),... )engine=innodb;

    講師要使用郵箱登錄,所以業務代碼中一定會出現類似于這樣的語句:

    mysql> select col1, col2 from teacher where email='xxx';

    如果email這個字段上沒有索引,那么這個語句就只能做 全表掃描。

    1、前綴索引

    MySQL是支持前綴索引的。默認地,如果你創建索引的語句不指定前綴長度,那么索引就會包含整個字符串。

    mysql> alter table teacher add index index1(email); #或 mysql> alter table teacher add index index2(email(6));

    這兩種不同的定義在數據結構和存儲上有什么區別呢?下圖就是這兩個索引的示意圖。


    以及

    如果使用的是index1(即email整個字符串的索引結構),執行順序是這樣的:

  • 從index1索引樹找到滿足索引值是’zhangssxyz@xxx.com’的這條記錄,取得ID2的值;
  • 到主鍵上查到主鍵值是ID2的行,判斷email的值是正確的,將這行記錄加入結果集;
  • 取index1索引樹上剛剛查到的位置的下一條記錄,發現已經不滿足email='zhangssxyz@xxx.com’的條件了,循環結束。
  • 這個過程中,只需要回主鍵索引取一次數據,所以系統認為只掃描了一行。

    如果使用的是index2(即email(6)索引結構),執行順序是這樣的:

  • 從index2索引樹找到滿足索引值是’zhangs’的記錄,找到的第一個是ID1;
  • 到主鍵上查到主鍵值是ID1的行,判斷出email的值不是’zhangssxyz@xxx.com’,這行記錄丟棄;
  • 取index2上剛剛查到的位置的下一條記錄,發現仍然是’zhangs’,取出ID2,再到ID索引上取整行然后判斷,這次值對了,將這行記錄加入結果集;
  • 重復上一步,直到在idxe2上取到的值不是’zhangs’時,循環結束。
  • 也就是說使用前綴索引,定義好長度,就可以做到既節省空間,又不用額外增加太多的查詢成本。前面已經講過區分度,區分度越高越好。因為區分度越高,意味著重復的鍵值越少。

    2、前綴索引對覆蓋索引的影響

    結論

    使用前綴索引就用不上覆蓋索引對查詢性能的優化了,這也是你在選擇是否使用前綴索引時需要考慮的一個因素。


    十、索引下推

    Index Condition Pushdown(ICP)是MySQL 5.6中新特性,是一種在存儲引擎層使用索引過濾數據的一種優化方式。
    ICP可以減少存儲引擎訪問基表的次數以及MySQL服務器訪問存儲引擎的次數。

    1、使用前后的掃描過程

    在不使用ICP索引掃描的過程

    storage層:只將滿足index key條件的索引記錄對應的整行記錄取出,返回給server層

    server 層:對返回的數據,使用后面的where條件過濾,直至返回最后一行。

    使用ICP掃描的過程

    • storage層:
      首先將index key條件滿足的索引記錄區間確定,然后在索引上使用index filter進行過濾。將滿足的indexfilter條件的索引記錄才去回表取出整行記錄返回server層。不滿足index filter條件的索引記錄丟棄,不回表、也不會返回server層。
    • server 層:
      對返回的數據,使用table filter條件做最后的過濾。


    使用前后的成本差別

    使用前,存儲層多返回了需要被index filter過濾掉的整行記錄

    使用ICP后,直接就去掉了不滿足index filter條件的記錄,省去了他們回表和傳遞server層的成本。

    ICP的 加速效果 取決于在存儲引擎內通過 ICP篩選 掉的數據的比例。

    2、ICP的使用條件

    ICP的使用條件

    ① 只能用于二級索引(secondary index)
    ②explain顯示的執行計劃中type值(join 類型)為 range 、 ref 、 eq_ref 或者ref_or_null。
    ③ 并非全部where條件都可以用ICP篩選,如果where條件的字段不在索引列中,還是要讀取整表的記錄到server端做where過濾。
    ④ ICP可以用于MyISAM和InnnoDB存儲引擎
    ⑤ MySQL 5.6版本的不支持分區表的ICP功能,5.7版本的開始支持。
    ⑥ 當SQL使用覆蓋索引時,不支持ICP優化方法。

    3、ICP使用案例

    案例1

    SELECT * FROM tuser WHERE NAME LIKE '張%' AND age = 10 AND ismale = 1;


    案例2:


    十一、普通索引 vs 唯一索引

    從性能的角度考慮,你選擇唯一索引還是普通索引呢?選擇的依據是什么呢?

    假設,我們有一個主鍵列為ID的表,表中有字段k,并且在k上有索引,假設字段 k 上的值都不重復。這個表的建表語句是:

    這個表的建表語句是:

    mysql> create table test(id int primary key,k int not null,name varchar(16),index (k))engine=InnoDB;

    表中R1~R5的(ID,k)值分別為(100,1)、(200,2)、(300,3)、(500,5)和(600,6)。

    1、查詢過程

    假設,執行查詢的語句是 select id from test where k=5。

    • 對于普通索引來說,查找到滿足條件的第一個記錄(5,500)后,需要查找下一個記錄,直到碰到第一個不滿足k=5條件的記錄。
    • 對于唯一索引來說,由于索引定義了唯一性,查找到第一個滿足條件的記錄后,就會停止繼續檢索。

    那么,這個不同帶來的性能差距會有多少呢?答案是,微乎其微 。

    2、更新過程

    為了說明普通索引和唯一索引對更新語句性能的影響這個問題,介紹一下changebuffer。

    當需要更新一個數據頁時,如果數據頁在內存中就直接更新,而如果這個數據頁還沒有在內存中的話,在不影響數據一致性的前提下, InooDB會將這些更新操作緩存在change buffer中 ,這樣就不需要從磁盤中讀入這個數據頁了。在下次查詢需要訪問這個數據頁的時候,將數據頁讀入內存,然后執行changebuffer中與這個頁有關的操作。通過這種方式就能保證這個數據邏輯的正確性。

    將change buffer中的操作應用到原數據頁,得到最新結果的過程稱為 merge 。除了 訪問這個數據頁 會觸發merge外,系統有 后臺線程會定期 merge。在數據庫正常關閉(shutdown) 的過程中,也會執行merge操作。

    如果能夠將更新操作先記錄在change buffer, 減少讀磁盤 ,語句的執行速度會得到明顯的提升。而且,數據讀入內存是需要占用 buffer pool 的,所以這種方式還能夠 避免占用內存,提高內存利用率。
    唯一索引的更新就不能使用change buffer ,實際上也只有普通索引可以使用。

    如果要在這張表中插入一個新記錄(4,400)的話,InnoDB的處理流程是怎樣的?

    3、change buffer的使用場景

  • 普通索引和唯一索引應該怎么選擇?其實,這兩類索引在查詢能力上是沒差別的,主要考慮的是對 更新性能 的影響。所以,建議你 盡量選擇普通索引 。
  • 在實際使用中會發現, 普通索引 和change buffer 的配合使用,對于 數據量大 的表的更新優化還是很明顯的。
  • 如果所有的更新后面,都馬上 伴隨著對這個記錄的查詢 ,那么你應該 關閉change buffer。而在其他情況下,change buffer都能提升更新性能。
  • 由于唯一索引用不上change buffer的優化機制,因此如果 業務可以接受 ,從性能角度出發建議優先考慮非唯一索引。但是如果"業務可能無法確保"的情況下,怎么處理呢?
    • 首先, 業務正確性優先 。我們的前提是“業務代碼已經保證不會寫入重復數據”的情況下,討論性能問題。如果業務不能保證,或者業務就是要求數據庫來做約束,那么沒得選,必須創建唯一索引。這種情況下,本節的意義在于,如果碰上了大量插入數據慢、內存命中率低的時候,給你多提供一個排查思路。
    • 然后,在一些“ 歸檔庫 ”的場景,你是可以考慮使用唯一索引的。比如,線上數據只需要保留半年,然后歷史數據保存在歸檔庫。這時候,歸檔數據已經是確保沒有唯一鍵沖突了。要提高歸檔效率,可以考慮把表里面的唯一索引改成普通索引。

    十二、其它查詢優化策略

    1、EXISTS 和 IN 的區分

    問題
    不太理解哪種情況下應該使用 EXISTS,哪種情況應該用 IN。選擇的標準是看能否使用表的索引嗎?

    2、COUNT(*)與COUNT(具體字段)效率

    問:在 MySQL 中統計數據表的行數,可以使用三種方式: SELECT COUNT(*) 、 SELECT COUNT(1) 和 SELECT COUNT(具體字段) ,使用這三者之間的查詢效率是怎樣的?

    3、關于SELECT(*)

    在表查詢中,建議明確字段,不要使用 * 作為查詢的字段列表,推薦使用SELECT <字段列表> 查詢。原因:

    ① MySQL 在解析的過程中,會通過 查詢數據字典 將"*"按序轉換成所有列名,這會大大的耗費資源和時間。

    ② 無法使用 覆蓋索引

    4、LIMIT 1 對優化的影響

    針對的是會掃描全表的 SQL 語句,如果你可以確定結果集只有一條,那么加上 LIMIT 1的時候,當找到一條結果的時候就不會繼續掃描了,這樣會加快查詢速度。

    如果數據表已經對字段建立了唯一索引,那么可以通過索引進行查詢,不會全表掃描的話,就不需要加上 LIMIT 1 了。

    5、多使用COMMIT

    只要有可能,在程序中盡量多使用 COMMIT,這樣程序的性能得到提高,需求也會因為 COMMIT 所釋放
    的資源而減少。

    COMMIT 會有所釋放的資源:

    • 回滾段上用于恢復數據的信息
    • 被程序語句獲得的鎖
    • redo / undo log buffer 中的空間
    • 管理上述 3 種資源中的內部花費

    十三、淘寶數據庫,主鍵如何設計的?

    聊一個實際問題:淘寶的數據庫,主鍵是如何設計的?

    某些錯的離譜的答案還在網上年復一年的流傳著,甚至還成為了所謂的MySQL軍規。
    其中,一個最明顯的錯誤就是關于MySQL的主鍵設計。

    大部分人的回答如此自信:用8字節的 BIGINT 做主鍵,而不要用INT。 錯!

    這樣的回答,只站在了數據庫這一層,而沒有 從業務的角度 思考主鍵。主鍵就是一個自增ID嗎?站在 2022年的新年檔口,用自增做主鍵,架構設計上可能 連及格都拿不到 。

    1、自增ID的問題

    自增ID做主鍵,簡單易懂,幾乎所有數據庫都支持自增類型,只是實現上各自有所不同而已。自增ID除了簡單,其他都是缺點,總體來看存在以下幾方面的問題:

  • 可靠性不高
    存在自增ID回溯的問題,這個問題直到最新版本的MySQL 8.0才修復。
  • 安全性不高
    對外暴露的接口可以非常容易猜測對應的信息。比如:/User/1/這樣的接口,可以非常容易猜測用戶ID的值為多少,總用戶數量有多少,也可以非常容易地通過接口進行數據的爬取。
  • 性能差
    自增ID的性能較差,需要在數據庫服務器端生成。
  • 交互多
    業務還需要額外執行一次類似 last_insert_id() 的函數才能知道剛才插入的自增值,這需要多一次的網絡交互。在海量并發的系統中,多1條SQL,就多一次性能上的開銷。
  • 局部唯一性
    最重要的一點,自增ID是局部唯一,只在當前數據庫實例中唯一,而不是全局唯一,在任意服務器間都是唯一的。對于目前分布式系統來說,這簡直就是噩夢。
  • 2、業務字段做主鍵

    為了能夠唯一地標識一個會員的信息,需要為 會員信息表 設置一個主鍵。那么,怎么為這個表設置主鍵,才能達到我們理想的目標呢? 這里我們考慮業務字段做主鍵。

    表數據如下:

    在這個表里,哪個字段比較合適呢?

    • 選擇卡號(cardno)
      會員卡號(cardno)看起來比較合適,因為會員卡號不能為空,而且有唯一性,可以用來 標識一條會員記錄。
    mysql> CREATE TABLE demo.membermaster -> ( -> cardno CHAR(8) PRIMARY KEY, -- 會員卡號為主鍵 -> membername TEXT, -> memberphone TEXT, -> memberpid TEXT, -> memberaddress TEXT, -> sex TEXT, -> birthday DATETIME -> ); Query OK, 0 rows affected (0.06 sec)

    不同的會員卡號對應不同的會員,字段“cardno”唯一地標識某一個會員。如果都是這樣,會員卡號與會員一一對應,系統是可以正常運行的。

    但實際情況是, 會員卡號可能存在重復使用 的情況。比如,張三因為工作變動搬離了原來的地址,不再到商家的門店消費了 (退還了會員卡),于是張三就不再是這個商家門店的會員了。但是,商家不想讓這個會 員卡空著,就把卡號是“10000001”的會員卡發給了王五。

    從系統設計的角度看,這個變化只是修改了會員信息表中的卡號是“10000001”這個會員 信息,并不會影響到數據一致性。也就是說,修改會員卡號是“10000001”的會員信息, 系統的各個模塊,都會獲取到修改后的會員信息,不會出現“有的模塊獲取到修改之前的會員信息,有的模塊獲取到修改后的會員信息,而導致系統內部數據不一致”的情況。因此,從 信息系統層面 上看是沒問題的。

    但是從使用 系統的業務層面 來看,就有很大的問題 了,會對商家造成影響。
    比如,我們有一個銷售流水表(trans),記錄了所有的銷售流水明細。2020 年 12 月 01 日,張三在門店購買了一本書,消費了 89 元。那么,系統中就有了張三買書的流水記錄,如下所示:

    接著,我們查詢一下 2020 年 12 月 01 日的會員銷售記錄:

    mysql> SELECT b.membername,c.goodsname,a.quantity,a.salesvalue,a.transdate -> FROM demo.trans AS a -> JOIN demo.membermaster AS b -> JOIN demo.goodsmaster AS c -> ON (a.cardno = b.cardno AND a.itemnumber=c.itemnumber); +------------+-----------+----------+------------+---------------------+ | membername | goodsname | quantity | salesvalue | transdate | +------------+-----------+----------+------------+---------------------+ | 張三 || 1.000 | 89.00 | 2020-12-01 00:00:00 | +------------+-----------+----------+------------+---------------------+ 1 row in set (0.00 sec)

    如果會員卡“10000001”又發給了王五,我們會更改會員信息表。導致查詢時:

    mysql> SELECT b.membername,c.goodsname,a.quantity,a.salesvalue,a.transdate -> FROM demo.trans AS a -> JOIN demo.membermaster AS b -> JOIN demo.goodsmaster AS c -> ON (a.cardno = b.cardno AND a.itemnumber=c.itemnumber); +------------+-----------+----------+------------+---------------------+ | membername | goodsname | quantity | salesvalue | transdate | +------------+-----------+----------+------------+---------------------+ | 王五 || 1.000 | 89.00 | 2020-12-01 00:00:00 | +------------+-----------+----------+------------+---------------------+ 1 row in set (0.01 sec)

    這次得到的結果是:王五在 2020 年 12 月 01 日,買了一本書,消費 89 元。顯然是錯誤的!
    結論:千萬不能把會員卡號當做主鍵。

    • 選擇會員電話 或 身份證號

    會員電話可以做主鍵嗎?不行的。在實際操作中,手機號也存在 被運營商收回 ,重新發給別人用的情況。

    那身份證號行不行呢?好像可以。因為身份證決不會重復,身份證號與一個人存在一一對 應的關系。可問題是,身份證號屬于 個人隱私 ,顧客不一定愿意給你。要是強制要求會員必須登記身份證號,會把很多客人趕跑的。其實,客戶電話也有這個問題,這也是我們在設計會員信息表的時候,允許身份證號和電話都為空的原因。

    所以,建議盡量不要用跟業務有關的字段做主鍵。畢竟,作為項目設計的技術人員,我們誰也無法預測在項目的整個生命周期中,哪個業務字段會因為項目的業務需求而有重復,或者重用之類的情況出現。

    經驗
    剛開始使用 MySQL 時,很多人都很容易犯的錯誤是喜歡用業務字段做主鍵,想當然地認為了解業務需求,但實際情況往往出乎意料,而更改主鍵設置的成本非常高。

    3、淘寶的主鍵設計

    在淘寶的電商業務中,訂單服務是一個核心業務。請問, 訂單表的主鍵 淘寶是如何設計的呢?是自增ID嗎?

    打開淘寶,看一下訂單信息:

    從上圖可以發現,訂單號不是自增ID!我們詳細看下上述4個訂單號:

    1550672064762308113 1481195847180308113 1431156171142308113 1431146631521308113

    訂單號是19位的長度,且訂單的最后5位都是一樣的,都是08113。且訂單號的前面14位部分是單調遞增的。

    大膽猜測,淘寶的訂單ID設計應該是:

    訂單ID = 時間 + 去重字段 + 用戶ID后6位尾號

    這樣的設計能做到全局唯一,且對分布式系統查詢及其友好。

    4、推薦的主鍵設計

    可通過改變UUID的時間排序,將時分秒放在前面,而不是默認的秒分時,就可做到有序
    非核心業務 :對應表的主鍵自增ID,如告警、日志、監控等信息。

    核心業務 :主鍵設計至少應該是全局唯一且是單調遞增`。全局唯一保證在各系統之間都是唯一的,單調遞增是希望插入時不影響數據庫性能。
    這里推薦最簡單的一種主鍵設計:UUID。

    UUID的特點
    全局唯一,占用36字節,數據無序,插入性能差。

    認識UUID

    • 為什么UUID是全局唯一的?
    • 為什么UUID占用36個字節?
    • 為什么UUID是無序的?

    MySQL數據庫的UUID組成如下所示:

    UUID = 時間+UUID版本(16字節)- 時鐘序列(4字節) - MAC地址(12字節)

    以UUID值e0ea12d4-6473-11eb-943c-00155dbaa39d舉例:

    為什么UUID是全局唯一的?
    在UUID中時間部分占用60位,存儲的類似TIMESTAMP的時間戳,但表示的是從1582-10-15 00:00:00.00到現在的100ns的計數。可以看到UUID存儲的時間精度比TIMESTAMPE更高,時間維度發生重復的概率降低到1/100ns。
    時鐘序列是為了避免時鐘被回撥導致產生時間重復的可能性。MAC地址用于全局唯一。

    為什么UUID占用36個字節?
    UUID根據字符串進行存儲,設計時還帶有無用"-"字符串,因此總共需要36個字節。

    為什么UUID是隨機無序的呢?
    因為UUID的設計中,將時間低位放在最前面,而這部分的數據是一直在變化的,并且是無序。
    改造UUID
    若將時間高低位互換,則時間就是單調遞增的了,也就變得單調遞增了。MySQL 8.0可以更換時間低位和時間高位的存儲方式,這樣UUID就是有序的UUID了。
    MySQL 8.0還解決了UUID存在的空間占用的問題,除去了UUID字符串中無意義的"-"字符串,并且將字符串用二進制類型保存,這樣存儲空間降低為了16字節。
    可以通過MySQL8.0提供的uuid_to_bin函數實現上述功能,同樣的,MySQL也提供了bin_to_uuid函數進行

    轉化:

    SET @uuid = UUID(); SELECT @uuid,uuid_to_bin(@uuid),uuid_to_bin(@uuid,TRUE);

    通過函數uuid_to_bin(@uuid,true)將UUID轉化為有序UUID了。全局唯一 + 單調遞增,這不就是我們想要的主鍵!

    有序UUID性能測試
    16字節的有序UUID,相比之前8字節的自增ID,性能和存儲空間對比究竟如何呢?
    我們來做一個測試,插入1億條數據,每條數據占用500字節,含有3個二級索引,最終的結果如下所示:
    從上圖可以看到插入1億條數據有序UUID是最快的,而且在實際業務使用中有序UUID在 業務端就可以生成 。
    還可以進一步減少SQL的交互次數。另外,雖然有序UUID相比自增ID多了8個字節,但實際只增大了3G的存儲空間,還可以接受

    在當今的互聯網環境中,非常不推薦自增ID作為主鍵的數據庫設計。更推薦類似有序UUID的全局唯一的實現。
    另外在真實的業務系統中,主鍵還可以加入業務和系統屬性,如用戶的尾號,機房的信息等。這樣的主鍵設計就更為考驗架構師的水平了。

    如果不是MySQL8.0 腫么辦?

    手動賦值字段做主鍵!

    比如,設計各個分店的會員表的主鍵,因為如果每臺機器各自產生的數據需要合并,就可能會出現主鍵重復的問題。

    可以在總部 MySQL 數據庫中,有一個管理信息表,在這個表中添加一個字段,專門用來記錄當前會員編號的最大值。

    門店在添加會員的時候,先到總部 MySQL 數據庫中獲取這個最大值,在這個基礎上加 1,然后用這個值作為新會員的“id”,同時,更新總部 MySQL 數據庫管理信息表中的當 前會員編號的最大值。

    這樣一來,各個門店添加會員的時候,都對同一個總部 MySQL 數據庫中的數據表字段進 行操作,就解決了各門店添加會員時會員編號沖突的問題。

    總結

    以上是生活随笔為你收集整理的Day517.索引优化与查询优化 -mysql的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    亚洲黄色一级视频 | 日韩免费一级a毛片在线播放一级 | 国产vs久久 | 丁香花中文字幕 | 免费精品视频在线 | 操操日日| 国产超碰在线观看 | 伊人午夜 | 国内视频在线观看 | av福利在线免费观看 | 精品国产1区2区3区 国产欧美精品在线观看 | 欧美精品二区 | 天天综合操 | 99久久精品国| 岛国片在线 | 国产a高清 | 亚洲不卡av一区二区三区 | 国产免费亚洲 | 日韩免费电影在线观看 | 久草视频中文在线 | 欧美 日韩 国产 成人 在线 | 狠狠色伊人亚洲综合成人 | 手机看国产毛片 | 久久久午夜精品理论片中文字幕 | 欧美一级黄色视屏 | 国产系列精品av | 91久久影院 | 日韩av播放在线 | 久久视频在线视频 | 97国产大学生情侣酒店的特点 | 免费视频成人 | 欧美一级专区免费大片 | 亚洲国产久 | 国产精品入口久久 | 成人免费视频a | 国产一二三四在线视频 | 成人av一区二区兰花在线播放 | 国产精品不卡在线 | 免费在线观看国产精品 | 在线不卡中文字幕播放 | 亚洲午夜精 | 久久久精品欧美一区二区免费 | 亚洲国产无 | 欧美少妇xxx | 日本bbbb摸bbbb| 五月色婷 | 国产91在线 | 美洲 | 青青河边草免费直播 | 五月婷婷操 | 丝袜美腿在线视频 | 在线观看日本韩国电影 | 99精品视频免费在线观看 | 久久久久国产免费免费 | 亚洲精品福利视频 | 伊人婷婷网 | 激情综合一区 | 日韩视频在线不卡 | 国产精品久久久久久久久久久久 | 久久黄色片子 | 久热电影 | 久久久综合香蕉尹人综合网 | 日本少妇久久久 | 九九九热精品免费视频观看网站 | 国产精品视频999 | 欧美日韩1区 | 夜色资源站国产www在线视频 | 91精品办公室少妇高潮对白 | 91精品办公室少妇高潮对白 | 日日日日干 | 人人爱人人爽 | 欧美视频在线观看免费网址 | 久久伦理电影网 | 在线 视频 一区二区 | av免费福利 | 欧美日韩精品电影 | 国产精品精品国产婷婷这里av | av黄色在线播放 | 91精品对白一区国产伦 | 午夜精品影院 | 91精品久久久久久 | wwwwww色| 六月婷操| 国产一区二区电影在线观看 | 五月天电影免费在线观看一区 | 日韩高清激情 | 国产成人在线观看免费 | 久久不见久久见免费影院 | 人人看看人人 | 狠狠久久综合 | 久草免费在线视频观看 | 国产精品久久久久久久久久尿 | 麻豆传媒视频在线免费观看 | 国产盗摄精品一区二区 | 808电影 | 日日操天天操狠狠操 | 九九综合久久 | 国产成人精品在线观看 | 久草在线精品观看 | 免费午夜av | 亚洲免费在线观看视频 | www.亚洲黄 | 欧美午夜精品久久久久久孕妇 | 天天插狠狠干 | 久久成 | 国产精品igao视频网网址 | 久久久96| 国产福利一区在线观看 | 欧美日韩国产一区 | 国产在线观看免费 | 91在线永久 | 日韩大片在线免费观看 | 日韩精品在线观看视频 | 成人中心免费视频 | 偷拍精品一区二区三区 | 国产精品久久久久久久久久久免费看 | 男女视频国产 | 免费看黄色毛片 | 99久久精品国产系列 | 在线电影 一区 | 免费黄色av | 亚洲精品免费在线观看视频 | 99国产精品视频免费观看一公开 | 黄色三级免费观看 | 亚洲国产精品人久久电影 | 少妇搡bbbb搡bbb搡aa | 日韩精品欧美专区 | 亚洲欧美日韩国产一区二区 | 亚洲91中文字幕无线码三区 | 免费日韩av电影 | 国产69久久久欧美一级 | 国产精品福利在线播放 | 久久久久国产一区二区三区 | 免费av电影网站 | 成人影视免费看 | 国产精品资源在线观看 | 最近免费观看的电影完整版 | 精品产品国产在线不卡 | 香蕉网在线播放 | 成人aaa毛片 | 9色在线视频 | 日韩视频一二三区 | 一级特黄av | 奇人奇案qvod | 天天爱天天操天天干 | 狠狠色丁香婷婷综合欧美 | 免费看国产曰批40分钟 | 91c网站色版视频 | 免费黄色av电影 | 色婷婷电影 | 一区二区三区国产精品 | 中文字幕成人在线 | 久久久久高清 | 亚洲国产中文字幕在线 | 成人免费在线观看入口 | 国产视频一区在线播放 | www.精选视频.com | 国产打女人屁股调教97 | 天天操天天操天天操 | 久久这里只精品 | 天天天天爽 | 亚洲自拍自偷 | 国产精品孕妇 | 国产手机精品视频 | 成人黄大片视频在线观看 | 婷婷网站天天婷婷网站 | 深爱激情站 | 色婷婷国产在线 | 中文字幕av全部资源www中文字幕在线观看 | 国产精品 中文在线 | 国产一区影院 | www.com在线观看 | 免费在线观看日韩视频 | 国产精品九九视频 | 国产精品一区二区久久精品爱微奶 | 91精品国产成 | 精品亚洲欧美一区 | 久久久福利影院 | 日本中文字幕在线免费观看 | 国产精品久久视频 | 国产一区高清在线观看 | 成人av教育 | 欧美日韩国产色综合一二三四 | 91精品夜夜 | 日韩视频在线播放 | 成人在线免费观看视视频 | bbb搡bbb爽爽爽 | 在线视频欧美亚洲 | 亚洲精品久久久久久久不卡四虎 | 亚洲精品免费观看视频 | 日韩精品一区二区三区三炮视频 | 麻豆传媒电影在线观看 | 超碰公开在线 | 欧美老人xxxx18| 亚洲成av | 成人在线免费视频观看 | 91麻豆精品国产91久久久久 | 99福利影院| 黄色毛片观看 | 日韩午夜在线观看 | 精品美女久久久久久免费 | 99国产精品视频免费观看一公开 | 亚洲一区二区视频 | 久久午夜色播影院免费高清 | 精品在线观看一区二区三区 | 欧美伦理一区 | 国产福利在线 | 亚洲国产日韩一区 | 国产在线视频在线观看 | 亚洲精品乱码白浆高清久久久久久 | 免费在线色电影 | 午夜av一区二区三区 | 久操操| 亚洲成人免费在线 | 国产天天综合 | 一级片免费视频 | 国产日韩精品一区二区三区 | 久久综合欧美 | 久久精品成人 | 成人av影视 | 成人一区二区三区在线观看 | 超碰97国产在线 | 国产亚洲免费的视频看 | 欧美91在线| 国产精品久久久久久69 | 狠狠躁18三区二区一区ai明星 | 亚洲最新视频在线 | 久久精品视频网站 | 69精品视频在线观看 | 久草在线手机观看 | 免费开视频 | 91视频 - v11av | 亚洲精品视频在线免费 | 色综合欧洲 | 欧美在线一级片 | 九九交易行官网 | 一区二区精品在线 | 超级av在线| 91av在线看 | 在线观看涩涩 | 亚洲精品动漫成人3d无尽在线 | 91成人精品| 亚洲精品中文在线观看 | 免费观看一区 | 精品国产乱码久久久久久浪潮 | 欧美在线视频精品 | 一区精品久久 | 欧美黄在线 | 欧美 国产 视频 | 最新日韩在线观看 | 精品国模一区二区 | 精品国产乱码久久久久久久 | 日日夜夜免费精品视频 | 最新av中文字幕 | 国产麻豆精品一区 | 亚州精品成人 | 伊人久在线 | 国产精品毛片久久久久久 | 欧美 日韩 国产 中文字幕 | 久久亚洲国产精品 | 久久人人97超碰com | 九九免费视频 | 中文字幕亚洲高清 | 午夜三级福利 | 人人玩人人弄 | 97在线精品 | 日韩高清在线一区 | 国产又粗又猛又黄又爽的视频 | 手机看片久久 | 国产综合91 | 不卡视频在线 | 四虎影视精品永久在线观看 | 亚洲日本va午夜在线影院 | 色偷偷88888欧美精品久久久 | av在线永久免费观看 | 一级欧美黄 | 国产精品久久久久久高潮 | 国产无套视频 | 久艹在线播放 | 久久草在线精品 | 国产视频中文字幕在线观看 | 四虎影视成人精品国库在线观看 | 国产精品女同一区二区三区久久夜 | 97人人网| 国产精品99久久久久久久久久久久 | 亚洲涩涩网站 | 日韩激情av在线 | 久久免费视频在线观看 | 国产美女免费 | 手机看片国产 | 欧美日本三级 | 99亚洲精品 | 手机成人免费视频 | 国产乱码精品一区二区三区介绍 | 91成人在线视频观看 | 91中文字幕 | 特级a毛片 | 96精品高清视频在线观看软件特色 | 久久人人爽视频 | 中文字幕一区二区三区四区久久 | 久久精品一二三区 | 在线黄色免费av | 麻豆久久精品 | 日日夜操 | 96av视频 | 久久国产精品视频 | 日韩av在线高清 | 成人精品国产免费网站 | 国产一二三四在线视频 | 亚洲成aⅴ人在线观看 | 国产一二区在线观看 | av在线8 | 久久久久免费精品视频 | 亚洲精品99久久久久中文字幕 | 成人aaa毛片| 亚洲午夜精品久久久 | 97超碰资源网 | 精品国产一区二区三区不卡 | 成人中心免费视频 | 日韩av片无码一区二区不卡电影 | 婷婷中文字幕在线观看 | 成片免费观看视频大全 | 成人v| 亚洲乱码久久 | 97成人在线免费视频 | 亚洲精品国产成人 | 99久久日韩精品免费热麻豆美女 | 91系列在线观看 | 色香天天 | 日本公妇色中文字幕 | 久久精品永久免费 | 欧美成年人在线视频 | 一区二区国产精品 | 激情在线网站 | www.黄色片.com| 国产又粗又猛又爽 | 国产精品麻豆一区二区三区 | 亚洲综合最新在线 | 91色影院 | 毛片的网址 | 亚洲视频一区二区三区在线观看 | 国产精品videoxxxx | 日韩综合视频在线观看 | 一区二区三区在线免费播放 | 久久婷婷网 | 波多野结衣精品 | 91在线操| 91精品播放 | 国产拍在线| 999视频在线播放 | 免费在线| 久久久久久国产精品999 | 色综合天天视频在线观看 | 日日夜色 | 国内免费久久久久久久久久久 | 国色天香永久免费 | 9797在线看片亚洲精品 | 天天综合在线观看 | 日日碰夜夜爽 | 精品黄色在线观看 | 在线看片91 | 国产成人精品免费在线观看 | 黄色a视频 | a国产精品 | 亚洲一级国产 | 黄色成人av | 成人九九视频 | 久久精品国产一区二区电影 | 久久久久久久久综合 | 色噜噜在线观看 | 欧美久久久一区二区三区 | 特级毛片aaa | 亚洲天堂香蕉 | 成人亚洲欧美 | 日韩视频精品在线 | 黄色精品一区二区 | 81国产精品久久久久久久久久 | 在线观看中文字幕 | 91九色蝌蚪视频 | 正在播放一区二区 | 国产精品v a免费视频 | 日韩精品免费一区二区 | 日本狠狠干 | 五月婷婷狠狠 | 亚洲h在线播放在线观看h | 96亚洲精品久久久蜜桃 | 国产精品久久精品国产 | 久久久久久高潮国产精品视 | 麻豆视频在线播放 | 激情视频国产 | 久热久草在线 | 日韩精品在线看 | 91大神一区二区三区 | 国产成人亚洲在线电影 | 超碰公开在线观看 | 天天五月天色 | 欧美性生活免费 | 视频国产一区二区三区 | 免费国产黄线在线观看视频 | 国产高清视频在线播放 | 免费视频你懂的 | 免费观看十分钟 | 亚洲精品免费在线视频 | 一区二区视频在线观看免费 | 草久久影院 | www.午夜视频 | 最新国产精品亚洲 | 在线观看免费高清视频大全追剧 | 色在线最新 | 欧美孕交vivoestv另类 | 亚洲在线视频观看 | 91九色网站| 日韩高清不卡一区二区三区 | 国产精品一区二区你懂的 | 51久久成人国产精品麻豆 | 国产97色在线 | 国产精品地址 | 天堂麻豆 | 人人干干人人 | 一级全黄毛片 | 免费看的黄网站软件 | 国产精品成人免费精品自在线观看 | 国产又粗又长的视频 | 久色小说 | 色多视频在线观看 | 色综合网| 久久精品影片 | 久久免费美女视频 | 三级免费黄 | 黄污网站在线观看 | 深夜福利视频一区二区 | 日日爽天天爽 | 国产一区二区在线影院 | 久久9999久久| 国产无套精品久久久久久 | 成人wwwxxx视频 | 激情网站| 天天爽天天爽 | 操久在线 | 在线观看色视频 | 欧美一级激情 | 狠狠综合| 久久久国产影视 | 少妇性bbb搡bbb爽爽爽欧美 | 天天干天天玩天天操 | 中文字幕免费看 | 国产a视频免费观看 | 久久香蕉国产精品麻豆粉嫩av | 亚洲精品xx| 99久久日韩精品免费热麻豆美女 | aaa黄色毛片| 在线观看亚洲电影 | 91免费国产在线观看 | 色婷婷在线播放 | 在线观看小视频 | 亚洲欧美日韩国产 | 狠狠色丁婷婷日日 | 成年人看片 | 国产一区在线视频观看 | 欧美在线日韩在线 | 99九九免费视频 | 精品亚洲二区 | 狠狠天天 | av中文在线影视 | 黄色大片av | 免费在线观看成年人视频 | 欧美一区二区三区在线视频观看 | 欧美激情精品久久久久久变态 | a级片在线播放 | 国产三级av在线 | 91大神在线看 | 国产精品美女在线观看 | 成年人在线免费视频观看 | 午夜性生活 | 黄色av电影 | 久久人人艹 | 婷婷综合电影 | 日日夜夜网| 狠狠色噜噜狠狠狠狠2021天天 | 在线 国产 亚洲 欧美 | 麻豆精品视频在线观看免费 | 97超碰在线资源 | 国产日韩精品久久 | 国产对白av | 韩国一区二区av | 五月婷婷视频在线 | 欧美亚洲精品在线观看 | 亚洲精品成人在线 | 超碰免费成人 | 国产一级三级 | 91高清不卡 | a久久久久久 | 91精品国产一区二区三区 | 激情影音先锋 | 最新久久免费视频 | 中文字幕在线观看不卡 | 不卡视频在线看 | 亚洲天堂网视频 | 亚洲免费在线播放视频 | 亚洲国产免费看 | 亚洲精品久 | av在线播放快速免费阴 | 久久精品99久久 | 麻豆视频免费入口 | 综合伊人久久 | 成人av电影免费在线观看 | 亚洲砖区区免费 | 亚洲免费在线观看视频 | 五月天丁香综合 | 91av免费在线观看 | 99久久久国产精品免费99 | 国产成人av网站 | 欧美极品少妇xbxb性爽爽视频 | 久久精品一区二区三区中文字幕 | 亚洲日本va午夜在线电影 | 国内揄拍国产精品 | 久久视频这里有精品 | 2022中文字幕在线观看 | 99精品视频在线免费观看 | 成人av免费在线观看 | 欧美日韩精品久久久 | 免费在线观看av电影 | 91麻豆精品国产自产在线 | 欧美韩日精品 | 久久综合五月 | 亚洲区精品 | 国产精品久久久亚洲 | 一二三四精品 | 国产成人a亚洲精品v | 狠狠干狠狠艹 | 日本久草电影 | 日韩av免费大片 | 在线观看午夜av | 国产免码va在线观看免费 | 91av久久| 久久999精品 | 免费在线国产视频 | av在线播放不卡 | 久久激情小说 | 久久精品艹 | 日日狠狠| 99久高清在线观看视频99精品热在线观看视频 | 日韩在线三级 | 国产免费久久 | 精品久久久久久国产 | 午夜12点| 国产亚洲一区二区三区 | 国产无限资源在线观看 | 亚洲视频久久久久 | 色婷婷狠狠干 | 国产一级免费在线观看 | 99精彩视频在线观看免费 | 欧美视频在线观看免费网址 | 91久久久国产精品 | 在线看污网站 | 五月天九九 | 精品久久久久久综合 | 日韩电影在线观看一区二区 | 99久久精品一区二区成人 | av大全免费在线观看 | 亚洲一二视频 | 美女亚洲精品 | 亚洲综合爱| 国产电影黄色av | 亚洲毛片一区二区三区 | 成人午夜精品 | 亚洲精品久久久蜜桃直播 | 亚洲最大av网 | 欧美在线aa | 欧美人zozo| a√资源在线 | 欧洲色吧 | 亚洲在线视频观看 | 婷婷播播网 | 国产黄大片 | 免费午夜av | 国产视频资源 | 国内精品久久久久久久久久久 | 在线看日韩 | 综合色婷婷| 中文字幕在线观看国产 | a级国产乱理伦片在线播放 久久久久国产精品一区 | 欧美日韩在线视频观看 | 欧美巨大荫蒂茸毛毛人妖 | 91一区在线观看 | 久久婷婷精品 | 91桃色在线免费观看 | 久久a级片| 亚洲天堂香蕉 | 可以免费观看的av片 | 91亚洲综合 | 日韩在线免费 | 成人资源在线 | 欧美色综合天天久久综合精品 | 黄色小说网站在线 | 怡红院av| 午夜电影中文字幕 | 久久99在线 | 日韩欧美一区二区在线播放 | av综合av| 国内精品二区 | 在线观看日韩av | 欧美日韩在线视频免费 | 欧洲精品亚洲精品 | 亚洲欧美视频在线播放 | 天天亚洲综合 | 手机看片国产日韩 | 伊人影院在线观看 | 久久九九国产视频 | 国产亚洲精品日韩在线tv黄 | 狠狠色噜噜狠狠狠狠 | 三级视频日韩 | 99色在线观看 | av免费观看网站 | 在线成人av | 视频一区二区在线 | 国产黄a三级三级三级三级三级 | av国产网站 | 久久综合精品国产一区二区三区 | 视频在线精品 | 在线观看视频国产 | 麻豆视频一区 | 欧美日韩精品二区第二页 | 久久99热精品 | 国产精品久久久久毛片大屁完整版 | 日韩欧美视频在线播放 | 又黄又爽免费视频 | 九九九九精品九九九九 | 日韩网站免费观看 | 久久精品久久精品久久精品 | 成人免费影院 | 波多野结衣网址 | 午夜精品一区二区三区在线 | 91在线网站 | 日韩三级.com | 国产精品国产三级国产aⅴ9色 | 欧美日韩一区二区三区视频 | 亚洲永久精品在线观看 | 黄p网站在线观看 | 欧美日韩另类在线 | 在线播放 日韩专区 | 国产精品美女久久久久久久网站 | 国产亚洲精品久久久久久久久久 | 99久久久国产精品免费99 | 午夜精品久久久久久久99热影院 | 国产伦精品一区二区三区在线 | 99热99热| 久草在线视频看看 | 夜夜骑天天操 | 国产一级黄色av | 美女黄频免费 | 精品视频9999 | 新版资源中文在线观看 | 97在线免费观看视频 | 日本一区二区免费在线观看 | 久久精品站 | 国产a级精品 | 夜夜爱av | 久久免费视频在线观看6 | 中文字幕不卡在线88 | 亚洲欧美日本一区二区三区 | 久久精品79国产精品 | 伊人久久电影网 | 一区二区三区 中文字幕 | 亚州精品天堂中文字幕 | 国产高清免费视频 | 在线最新av| 精品国产aⅴ麻豆 | 91精品久久久久久粉嫩 | 久久免费视频观看 | 在线 视频 一区二区 | 久久久久久久久久久影视 | 狠狠艹夜夜干 | 中文字幕韩在线第一页 | 亚洲精品国精品久久99热一 | 黄色在线网站噜噜噜 | 国产一级视频 | 91精品在线观看入口 | 亚洲欧美国产精品va在线观看 | 九九九在线观看视频 | 国产特黄色片 | 免费观看性生活大片3 | 日本电影久久 | 日本黄色黄网站 | 草久在线视频 | 色欧美日韩| 国产日韩视频在线观看 | 激情五月在线视频 | 国产精品入口久久 | 最新日韩视频 | 免费男女羞羞的视频网站中文字幕 | 91在线免费看片 | 日日干夜夜草 | 亚洲国产精品999 | 免费看成人a | 在线一二三四区 | 色婷婷免费| 成年人黄色免费视频 | 久久久一本精品99久久精品66 | 狠狠的干狠狠的操 | 一级黄色网址 | a在线观看国产 | 国产欧美三级 | 午夜av影院 | 九九综合在线 | 久久午夜网 | 91看片看淫黄大片 | 国产色啪| 69视频在线播放 | 国产精品系列在线观看 | 九九视频免费 | 久久久福利影院 | 香蕉视频国产在线观看 | 深爱婷婷 | 亚洲视频免费在线观看 | 成人午夜电影网 | www.亚洲精品视频 | 中文字幕中文字幕 | 色中色综合 | 婷婷国产一区二区三区 | 国产午夜免费视频 | 国产亚洲精品美女久久 | 精品久久久久一区二区国产 | 免费观看成人av | 日韩视频中文字幕在线观看 | 久久福利影视 | 在线观看黄污 | 91天堂素人约啪 | 91成人网在线 | 欧美精品在线一区二区 | 国产精品日韩久久久久 | 国产精品久久99精品毛片三a | 黄色在线看网站 | 免费色黄 | 精品国产一区二区三区四区在线观看 | 日本在线视频一区二区三区 | 一区二区三区在线免费观看视频 | 久久精品影视 | 亚洲一区二区三区毛片 | 久草免费在线观看视频 | 精品一区二区在线观看 | 亚洲综合色丁香婷婷六月图片 | 91chinesexxx| 一区二区视频电影在线观看 | 精品福利在线 | 欧美久久久久久久久久久久久 | 精品国产久 | 一区二区三区在线免费播放 | 国产丝袜一区二区三区 | av免费在线看网站 | 美女免费视频黄 | 在线观看播放av | 午夜黄色大片 | 成人不用播放器 | 久久在线播放 | 久久女同性恋中文字幕 | 波多野结衣综合网 | 人人澡人人爽欧一区 | 天天操天天舔天天爽 | 国产亚洲日 | 国产又粗又猛又黄又爽的视频 | 91在线精品一区二区 | 欧美成人精品欧美一级乱黄 | 亚洲国产av精品毛片鲁大师 | 亚洲闷骚少妇在线观看网站 | 欧美成人久久 | 国产精品久久久久婷婷二区次 | 国产精品久久久久久99 | 国产精品日韩久久久久 | 丁香婷婷色月天 | 九九热国产视频 | 免费看国产曰批40分钟 | 永久黄网站色视频免费观看w | 插久久| 蜜桃视频在线观看一区 | 久久免费看av | 五月婷婷视频在线 | 国产一级久久 | 午夜精品一区二区三区免费视频 | 麻豆视频在线播放 | 免费视频网 | 涩涩在线| 中文字幕在线观看网址 | 日日干天天| 久久丁香网 | 久国产在线播放 | 免费看的黄色的网站 | 国产精品亚 | 毛片永久免费 | 国产自产在线视频 | 国产精品美女久久久久久 | 国产极品尤物在线 | 高清久久久久久 | 99资源网 | 99色在线视频 | 曰韩精品 | 午夜影院一级片 | 激情伊人五月天久久综合 | 国产精品麻豆一区二区三区 | 久久国产成人午夜av影院宅 | 免费毛片aaaaaa | 最近日本韩国中文字幕 | 久久精品人人做人人综合老师 | 欧美福利视频 | 国产小视频免费在线观看 | 西西www444| 91精品国产综合久久婷婷香蕉 | 亚洲欧洲国产视频 | 久草免费福利在线观看 | 日韩xxxx视频 | 日韩 | 国产在线观看地址 | 国产精品女主播一区二区三区 | 成人av久久 | 黄色大片av| 在线观看黄色av | 欧美最猛性xxxx | 国产精品久久久一区二区三区网站 | 91日韩在线播放 | 精品在线你懂的 | 国产成人三级三级三级97 | 亚洲精品五月 | 久久久高清视频 | 日韩高清不卡一区二区三区 | 日日干天天操 | 97在线观看免费高清 | 亚洲视频免费在线观看 | 欧洲一区二区三区精品 | 亚洲综合视频在线 | 97视频在线观看播放 | 麻豆91小视频| 亚洲在线黄色 | 免费看一级黄色 | 中文区中文字幕免费看 | 久久影视精品 | 99r精品视频在线观看 | 综合久久久久久久久 | 狠狠久久婷婷 | 日韩有码专区 | 久黄色 | 国产精品99久久久久久人免费 | 91一区啪爱嗯打偷拍欧美 | 欧洲高潮三级做爰 | 欧美精品在线视频 | 久久久久一区二区三区四区 | 久久久免费看片 | 久草在线久 | 国产精品久久久久久影院 | 天天草天天摸 | 黄色成品视频 | 日韩视频 一区 | 国产无区一区二区三麻豆 | 黄p在线播放 | 免费av 在线 | 日韩精品不卡 | 在线精品国产 | 我要看黄色一级片 | 精品久久久久久亚洲 | 黄色一级免费 | 狠狠狠狠狠狠操 | 国产精品久久久久四虎 | 国产精品免费在线视频 | 国内精品久久久久久久 | 久久久久久久毛片 | 天天插日日插 | 国产精品国产亚洲精品看不卡15 | 天天爱av导航 | 在线国产观看 | 九九久久久久久久久激情 | 手机av片| 天天爱天天射天天干天天 | 操天天操| 18av在线视频| av线上看 | 四虎永久免费在线观看 | 激情视频二区 | 免费网站黄 | 欧美精品一区二区免费 | 久久久www| 国产麻豆视频网站 | 久久精品影片 | 精品国产一区二区三区久久久 | 国产成人久久av977小说 | 这里只有精彩视频 | 国产a网站 | 免费日韩 精品中文字幕视频在线 | www.com在线观看| 黄色小网站免费看 | 日本不卡一区二区三区在线观看 | 人九九精品 | 99热这里是精品 | 午夜精品久久 | 国内视频在线观看 | 网站在线观看日韩 | 中文字幕在线播放一区 | 成人在线视频你懂的 | 18女毛片 | 在线免费观看视频一区二区三区 | 婷婷久久综合九色综合 | 久草在线视频首页 | 婷婷久久综合九色综合 | 操天天操| 日本精品一区二区在线观看 | 国产精品久久久久久久久久免费看 | 日日干影院 | 成人h在线 | 美女久久视频 | 久久神马影院 | 亚洲成人精品在线观看 | 中文免费在线观看 | 99视频国产精品 | 免费无遮挡动漫网站 | 国产人在线成免费视频 | 日本 在线 视频 中文 有码 | 欧美午夜性生活 | 日韩精品视频在线免费观看 | 中文字幕在线观看播放 | 国产福利久久 | 91精品视频免费 | 亚洲国产精品99久久久久久久久 | 免费看的毛片 | 中文字幕欧美日韩va免费视频 | 欧美激情综合网 | 在线直播av | 中文字幕电影在线 | 成人av网站在线 | 精品久久久久久国产 | 日韩高清在线一区二区三区 | 久99久精品视频免费观看 | 免费三级黄色 | 欧美一区二区三区在线播放 | 久久夜色网 | 国产 欧美 日产久久 | 91九色丨porny丨丰满6 | 在线观看免费av网站 | 天天综合网 天天 | 亚洲综合情 | 天天操·夜夜操 | 在线国产91| 一级特黄av | 久久激情五月丁香伊人 | 日本中文字幕电影在线免费观看 | 亚洲 成人 欧美 | 91丨九色丨国产丨porny精品 | 中文字幕观看av | 99久久超碰中文字幕伊人 | 久久久这里有精品 | 天堂激情网 | 久久伊人国产精品 | 亚洲黄色在线 | 免费在线观看av不卡 | 日韩精品国产一区 | 国产区第一页 | 九九九热| 久久激情视频网 | 五月网婷婷 | 久久99深爱久久99精品 | www.av中文字幕.com | 夜色.com | 大荫蒂欧美视频另类xxxx | 国产精品久久久一区二区 | av+在线播放在线播放 | 国产精品久久久久久久久久妇女 | 99精品视频免费 | 丁香在线| 亚洲欧美日韩国产一区二区三区 | se视频网址 | 国产美女在线精品免费观看 | 国产高清在线a视频大全 | 丁香婷婷在线观看 | 成人蜜桃视频 | 夜夜躁日日躁狠狠躁 | 最近最新最好看中文视频 | 最近2019好看的中文字幕免费 | 97日日碰人人模人人澡分享吧 | 精品久久久久久久久久久久久久久久久久 | 在线观看黄色av | 麻花豆传媒一二三产区 | 综合五月 | 日本视频网| 国产精品入口麻豆www | 天天操天天干天天 | 91热精品视频 | 欧美极品一区二区三区 | 天天插天天狠天天透 | 美女网站色在线观看 | 97视频在线观看免费 | 天天操天天操天天爽 | 99视| 国产专区日韩专区 | 免费观看91 | 夜夜视频欧洲 | 手机成人av | 91亚洲国产成人久久精品网站 | 高清av中文在线字幕观看1 | 国产精品久久久久久久久婷婷 | 亚洲精品午夜国产va久久成人 | 亚洲视频1区2区 | 亚洲人成人天堂h久久 |