日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

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

数据库

mysql8.0 之 sql 优化《三B》 之 优化范围查询 总览 总结

發布時間:2023/12/8 数据库 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql8.0 之 sql 优化《三B》 之 优化范围查询 总览 总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

單部分索引的范圍訪問方法

單部分索引的范圍條件的定義如下:

  • 對于這兩種BTREE和?HASH索引,使用時具有恒定值的關鍵部分的比較是一個范圍條件 = <=>,in(),is null or,is not null運營商。
  • 另外,對于BTREE索引,使用時具有恒定值的關鍵部分的比較是一個范圍條件 >,<,>=,<=,between,!=,<>運營商,或者like比較,如果該參數 like是一個常數字符串不與通配符開始。
  • 對于所有索引類型,多個范圍條件與范圍條件組合?or?或?AND形成范圍條件。

?

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

SELECT * FROM t1WHERE key_col > 1AND key_col < 10;SELECT * FROM t1WHERE key_col = 1OR key_col IN (15,18,20);SELECT * FROM t1WHERE key_col LIKE 'ab%'OR key_col BETWEEN 'bar' AND 'foo';

?

MySQL嘗試從WHERE每個可能索引的子句中提取范圍條件?。在提取過程期間,丟棄不能用于構建范圍條件的條件,組合產生重疊范圍的條件,并且去除產生空范圍的條件。

請考慮以下語句,其中?key1是索引列?nonkey且未編入索引:

SELECT * FROM t1 WHERE(key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR(key1 < 'bar' AND nonkey = 4) OR(key1 < 'uux' AND key1 > 'z');

?

密鑰的提取過程key1如下:

  • 從原始WHERE條款開始:

    (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR (key1 < 'bar' AND nonkey = 4) OR (key1 < 'uux' AND key1 > 'z')
  • 刪除nonkey = 4并key1 LIKE '%b'因為它們不能用于范圍掃描。刪除它們的正確方法是用它們替換它們TRUE,這樣我們在進行范圍掃描時不會錯過任何匹配的行。用TRUE產量替換它們:

    (key1 < 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR (key1 < 'bar' AND TRUE) OR (key1 < 'uux' AND key1 > 'z')
  • 折疊條件始終為真或假:

    • (key1 LIKE 'abcde%' OR TRUE)?總是如此

    • (key1 < 'uux' AND key1 > 'z')?總是假的

    用常數替換這些條件會產生:

    (key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)

    刪除不必要的TRUE和?FALSE常量會產生:

    (key1 < 'abc') OR (key1 < 'bar')
  • 將重疊間隔組合成一個會產生用于范圍掃描的最終條件:

    (key1 < 'bar')
  • 通常(并且如前面的示例所示),用于范圍掃描的條件比該WHERE子句的限制性更小。MySQL執行額外的檢查以過濾掉滿足范圍條件但不滿足完整WHERE子句的行。

    范圍條件提取算法可以處理?任意深度的嵌套 and/or構造,其輸出不依賴于條件在WHERE子句中出現的順序?。

    ?

    多部分索引的范圍訪問方法

    以下描述更詳細地說明了范圍條件如何適用于多部分索引。

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

      key_part1 cmp const1 AND key_part2 cmp const2 AND ... AND key_partN cmp constN;

      這里const1,?const2...是常數,cmp是一個?=,?<=>或者IS NULL比較運營商,以及條件覆蓋所有指數部分。(也就是說,有一些N?條件,一個用于N-part索引的每個部分?。)例如,以下是三部分HASH索引的范圍條件?:

      key_part1 = 1 AND key_part2 IS NULL AND key_part3 = 'foo'

    例子:

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

    單個間隔是:

    ('foo',10,-inf) < (key_part1,key_part2,key_part3) < ('foo',+inf,+inf)

    例子:

    (key_part1 = 1 AND key_part2 < 2) OR (key_part1 > 5) 間隔是:(1,-inf) < (key_part1,key_part2) < (1,2) (5,-inf) < (key_part1,key_part2)

    ?

    例子:

    key_part1 >= 1 AND key_part2 < 2 但是,事實上,條件轉換為:key_part1 >= 1 AND key_part2 IS NOT NULL

    ?

    多值比較的等價范圍優化

    col_name IN(val1, ..., valN) col_name = val1 OR ... OR col_name = valN

    在MySQL 8.0中,對于滿足所有這些條件的查詢,可以進行索引潛水跳過:

    • 查詢用于單個表,而不是多個表的連接。

    • 存在單索引FORCE INDEX索引提示。我們的想法是,如果強制使用索引,那么從潛在的索引中獲取額外開銷就無法獲得任何好處。

    • 該索引不是唯一的而不是?FULLTEXT索引。

    • 沒有子查詢。

    • 不DISTINCT,GROUP BY或ORDER BY條款存在。

    ?

    跳過掃描范圍訪問方法

    CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY(f1, f2)); INSERT INTO t1 VALUES(1,1), (1,2), (1,3), (1,4), (1,5),(2,1), (2,2), (2,3), (2,4), (2,5); INSERT INTO t1 SELECT f1, f2 + 5 FROM t1; INSERT INTO t1 SELECT f1, f2 + 10 FROM t1; INSERT INTO t1 SELECT f1, f2 + 20 FROM t1; INSERT INTO t1 SELECT f1, f2 + 40 FROM t1; ANALYZE TABLE t1;EXPLAIN SELECT f1, f2 FROM t1 WHERE f2 > 40;

    對于前面顯示的數據集,算法的運行方式如下:

  • 獲取第一個關鍵部分(f1 = 1)的第一個不同值。

  • 根據第一個和第二個關鍵部分構造范圍(f1 = 1 AND f2 > 40)。

  • 執行范圍掃描。

  • 獲取第一個關鍵部分(f1 = 2)的下一個不同值。

  • 根據第一個和第二個關鍵部分構造范圍(f1 = 2 AND f2 > 40)。

  • 執行范圍掃描。

  • 行構造函數表達式的范圍優化

    優化器能夠將范圍掃描訪問方法應用于此表單的查詢:

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

    優化為:

    SELECT ... FROM t1 WHERE ( col_1 = 'a' AND col_2 = 'b' ) OR ( col_1 = 'c' AND col_2 = 'd' );

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

    • 只使用IN()謂詞,而不是NOT IN()
    • IN()謂詞的左側?,行構造函數僅包含列引用。
    • IN()謂詞的右側?,行構造函數僅包含運行時常量,這些常量是在執行期間綁定到常量的文字或本地列引用。
    • IN()謂詞的右側?,有多個行構造函數。

    ?

    限制內存使用范圍優化

    要控制范圍優化程序可用的內存,請使用?range_optimizer_max_mem_size系統變量:

    • 值為0表示“?無限制。”

    • 值大于0時,優化程序會在考慮范圍訪問方法時跟蹤消耗的內存。如果要超過指定的限制,則放棄范圍訪問方法,并考慮其他方法,包括全表掃描。這可能不太理想。如果發生這種情況,會發生以下警告(N當前?range_optimizer_max_mem_size值在哪里?):

    要估計處理范圍表達式所需的內存量,請使用以下準則:

    • 對于諸如以下的簡單查詢,其中有一個候選鍵用于范圍訪問方法,每個謂詞組合OR?使用大約230個字節:

      SELECT COUNT(*) FROM t WHERE a=1 OR a=2 OR a=3 OR .. . a=N;
    • 類似地,對于諸如以下的查詢,每個謂詞組合AND使用大約125個字節:

      SELECT COUNT(*) FROM t WHERE a=1 AND b=1 AND c=1 ... N;
    • 對于帶in()謂詞的查詢:

      SELECT COUNT(*) FROM t WHERE a IN (1,2, ..., M) AND b IN (1,2, ..., N);

      in()列表?中的每個文字值都?計為一個謂詞組合or。如果有兩個in()?列表,則組合的謂詞 or數是每個列表中文字值的數量的乘積。因此,與or前一種情況相結合的謂詞數?是?M×?N。


    ?

    ?

    優化總篇:https://blog.csdn.net/weixin_42749765/article/details/88223273

    ?

    ?

    文章持續更新,轉發表明出處,方便更新!

    ?

    ?

    ?

    ?

    總結

    以上是生活随笔為你收集整理的mysql8.0 之 sql 优化《三B》 之 优化范围查询 总览 总结的全部內容,希望文章能夠幫你解決所遇到的問題。

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