MySQL Range Optimization

来源:http://www.cnblogs.com/ivictor/archive/2016/02/17/5195260.html
-Advertisement-
Play Games

8.2.1.3 Range Optimization MYSQL的Range Optimization的目的還是儘可能的使用索引 The range access method uses a single index to retrieve a subset of table rows that a


8.2.1.3 Range Optimization

MYSQL的Range Optimization的目的還是儘可能的使用索引

The range access method uses a single index to retrieve a subset of table rows that are contained within one or several index value intervals. It can be used for a single-part or multiple-part index. The following sections give descriptions of conditions under which the optimizer uses range access.

8.2.1.3.1 The Range Access Method for Single-Part Indexes

針對單一索引

For a single-part index, index value intervals can be conveniently represented by corresponding conditions in theWHERE clause, so we speak of range conditions rather than intervals.”

The definition of a range condition for a single-part index is as follows:

  • For both BTREE and HASH indexes, comparison of a key part with a constant value is a range condition when using the =<=>IN()IS NULL, or IS NOT NULL operators.

  • Additionally, for BTREE indexes, comparison of a key part with a constant value is a range condition when using the ><>=<=BETWEEN!=, or <> operators, or LIKE comparisons if the argument to LIKE is a constant string that does not start with a wildcard character.

  • For all types of indexes, multiple range conditions combined with OR or AND form a range condition.

    對於BTREE索引和HASH索引來說,索引的範圍優化基本上只適用於等值查詢。譬如=, <=>, IN(), IS NULL, IS NOT NULL操作符。

    相對於HASH索引,BTREE索引同樣支持非等值查詢,譬如>, <, >=, <=, BETWEEN, !=, <>和LIKE(註意,like的常量值不能以通配符開頭)

Constant value” in the preceding descriptions means one of the following:

  • A constant from the query string

  • A column of a const or system table from the same join

  • The result of an uncorrelated subquery

Any expression composed entirely from subexpressions of the preceding types

常量值一般指三種:查詢條件為常量,const表或system表,非關聯子查詢的結果

其中,const表指的是最多只有一個匹配行,譬如基於主鍵的查詢:

SELECT * FROM tbl_name WHERE primary_key=1;

SELECT * FROM tbl_name
  WHERE primary_key_part1=1 AND primary_key_part2=2;

Here are some examples of queries with range conditions in the WHERE clause:

SELECT * FROM t1
  WHERE key_col > 1
  AND key_col < 10;

SELECT * FROM t1
  WHERE key_col = 1
  OR key_col IN (15,18,20);

SELECT * FROM t1
  WHERE key_col LIKE 'ab%'
  OR key_col BETWEEN 'bar' AND 'foo';

Some nonconstant values may be converted to constants during the constant propagation phase.

以下是MySQL提取範圍條件的思路,並不是等價變換,目的還是在於儘可能的使用索引的範圍查詢,包括後面的紅色部分也提到,這樣變換後的條件會沒有原來的條件嚴格,MySQL這樣做的目的在於利用索引過濾掉很大一部分記錄,然後再對剩下的記錄進行額外的篩選。

MySQL tries to extract range conditions from the WHERE clause for each of the possible indexes. During the extraction process, conditions that cannot be used for constructing the range condition are dropped, conditions that produce overlapping ranges are combined, and conditions that produce empty ranges are removed.

Consider the following statement, where key1 is an indexed column and nonkey is not indexed:

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

The extraction process for key key1 is as follows:

  1. Start with original WHERE clause:

    (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR
    (key1 < 'bar' AND nonkey = 4) OR
    (key1 < 'uux' AND key1 > 'z')
    
  2. Remove nonkey = 4 and key1 LIKE '%b' because they cannot be used for a range scan. The correct way to remove them is to replace them with TRUE, so that we do not miss any matching rows when doing the range scan. Having replaced them with TRUE, we get:

    (key1 < 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR
    (key1 < 'bar' AND TRUE) OR
    (key1 < 'uux' AND key1 > 'z')
    
  3. Collapse conditions that are always true or false:

    • (key1 LIKE 'abcde%' OR TRUE) is always true

    • (key1 < 'uux' AND key1 > 'z') is always false

    Replacing these conditions with constants, we get:

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

    Removing unnecessary TRUE and FALSE constants, we obtain:

    (key1 < 'abc') OR (key1 < 'bar')
    
  4. Combining overlapping intervals into one yields the final condition to be used for the range scan:

    (key1 < 'bar')
    

In general (and as demonstrated by the preceding example), the condition used for a range scan is less restrictive than the WHERE clause. MySQL performs an additional check to filter out rows that satisfy the range condition but not the full WHERE clause.

The range condition extraction algorithm can handle nested AND/OR constructs of arbitrary depth, and its output does not depend on the order in which conditions appear in WHERE clause.

MySQL does not support merging multiple ranges for the range access method for spatial indexes. To work around this limitation, you can use a UNION with identical SELECT statements, except that you put each spatial predicate in a different SELECT.

8.2.1.3.2 The Range Access Method for Multiple-Part Indexes

針對複合索引

Range conditions on a multiple-part index are an extension of range conditions for a single-part index. A range condition on a multiple-part index restricts index rows to lie within one or several key tuple intervals. Key tuple intervals are defined over a set of key tuples, using ordering from the index.

For example, consider a multiple-part index defined as key1(key_part1key_part2key_part3), and the following set of key tuples listed in key order:

key_part1  key_part2  key_part3
  NULL       1          'abc'
  NULL       1          'xyz'
  NULL       2          'foo'
   1         1          'abc'
   1         1          'xyz'
   1         2          'abc'
   2         1          'aaa'

The condition key_part1 = 1 defines this interval:

(1,-inf,-inf) <= (key_part1,key_part2,key_part3) < (1,+inf,+inf)

The interval covers the 4th, 5th, and 6th tuples in the preceding data set and can be used by the range access method.

By contrast, the condition key_part3 = 'abc' does not define a single interval and cannot be used by the range access method.

如果使用前導列key_part1,則可以使用索引,如果直接使用key_part3,則不能使用索引。

The following descriptions indicate how range conditions work for multiple-part indexes in greater detail.

  • For HASH indexes, each interval containing identical values can be used. This means that the interval can be produced only for conditions in the following form:

    key_part1cmpconst1
    AND key_part2cmpconst2
    AND ...
    AND key_partNcmpconstN;
    

    Here, const1const2, … are constants, cmp is one of the =<=>, or IS NULL comparison operators, and the conditions cover all index parts. (That is, there are N conditions, one for each part of an N-part index.) For example, the following is a range condition for a three-part HASH index:

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

    For the definition of what is considered to be a constant, see Section 8.2.1.3.1, “The Range Access Method for Single-Part Indexes”.

  • For a BTREE index, an interval might be usable for conditions combined with AND, where each condition compares a key part with a constant value using =<=>IS NULL><>=<=!=<>BETWEEN, or LIKE 'pattern' (where 'pattern' does not start with a wildcard). An interval can be used as long as it is possible to determine a single key tuple containing all rows that match the condition (or two intervals if <>or != is used).

    The optimizer attempts to use additional key parts to determine the interval as long as the comparison operator is =<=>, or IS NULL. If the operator is ><>=<=!=<>BETWEEN, or LIKE, the optimizer uses it but considers no more key parts. For the following expression, the optimizer uses = from the first comparison. It also uses >= from the second comparison but considers no further key parts and does not use the third comparison for interval construction:

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

    The single interval is:

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

    It is possible that the created interval contains more rows than the initial condition. For example, the preceding interval includes the value ('foo', 11, 0), which does not satisfy the original condition.

       對於BTREE的複合索引來說,一旦其中的一個索引列使用了非等值查詢,則在其後的索引列將無法繼續使用索引。

       譬如:key_part1 = 'foo' AND key_part2 >= 10 AND key_part3 > 10

       因為第二個索引列key_part2使用了非等值查詢,則第三個索引列key_part3無法使用索引。

       所以,它的變換形式為('foo',10,-inf) < (key_part1,key_part2,key_part3) < ('foo',+inf,+inf),

       而不是('foo',10,10) < (key_part1,key_part2,key_part3) < ('foo',+inf,+inf)

  • If conditions that cover sets of rows contained within intervals are combined with OR, they form a condition that covers a set of rows contained within the union of their intervals. If the conditions are combined withAND, they form a condition that covers a set of rows contained within the intersection of their intervals. For example, for this condition on a two-part index:

    (key_part1 = 1 AND key_part2 < 2) OR (key_part1 > 5)
    

    The intervals are:

    (1,-inf) < (key_part1,key_part2) < (1,2)
    (5,-inf) < (key_part1,key_part2)
    

    In this example, the interval on the first line uses one key part for the left bound and two key parts for the right bound. The interval on the second line uses only one key part. The key_len column in the EXPLAINoutput indicates the maximum length of the key prefix used.

    In some cases, key_len may indicate that a key part was used, but that might be not what you would expect. Suppose that key_part1 and key_part2 can be NULL. Then the key_len column displays two key part lengths for the following condition:

    key_part1 >= 1 AND key_part2 < 2
    

    But, in fact, the condition is converted to this:

    key_part1 >= 1 AND key_part2 IS NOT NULL
    

Section 8.2.1.3.1, “The Range Access Method for Single-Part Indexes”, describes how optimizations are performed to combine or eliminate intervals for range conditions on a single-part index. Analogous steps are performed for range conditions on multiple-part indexes.

8.2.1.3.3 Equality Range Optimization of Many-Valued Comparisons

Consider these expressions, where col_name is an indexed column:

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

Each expression is true if col_name is equal to any of several values. These comparisons are equality range comparisons (where the range” is a single value). The optimizer estimates the cost of reading qualifying rows for equality range comparisons as follows:

  • If there is a unique index on col_name, the row estimate for each range is 1 because at most one row can have the given value.

  • Otherwise, the optimizer can estimate the row count for each range using dives into the index or index statistics.

如果是唯一索引,則每一個range的對應的row為1。如果不是唯一索引,優化器有兩個方式來評估每個range對應的行數:index dives和index statistics。其中,index dives能提供更精確的估計,但是成本會比較高,index statistics速度較快,但精度沒有index dives高,選擇哪種方式由eq_range_index_dive_limit決定,5.7.3之前預設值為10,指的是當range的個數小於或等於9時,MySQL預設會選擇index dives,超過9個,則選擇index statistics。

With index dives, the optimizer makes a dive at each end of a range and uses the number of rows in the range as the estimate. For example, the expression col_name IN (10, 20, 30) has three equality ranges and the optimizer makes two dives per range to generate a row estimate. Each pair of dives yields an estimate of the number of rows that have the given value.

Index dives provide accurate row estimates, but as the number of comparison values in the expression increases, the optimizer takes longer to generate a row estimate. Use of index statistics is less accurate than index dives but permits faster row estimation for large value lists.

The eq_range_index_dive_limit system variable enables you to configure the number of values at which the optimizer switches from one row estimation strategy to the other. To disable use of statistics and always use index dives, set eq_range_index_dive_limit to 0. To permit use of index dives for comparisons of up to Nequality ranges, set eq_range_index_dive_limit to N + 1.

To update table index statistics for best estimates, use ANALYZE TABLE.

8.2.1.3.4 Range Optimization of Row Constructor Expressions

As of MySQL 5.7.3, the optimizer is able to apply the range scan access method to queries of this form:

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

Previously, for range scans to be used it was necessary for the query to be written as:

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

For the optimizer to use a range scan, queries must satisfy these conditions:

  • Only IN predicates can be used, not NOT IN.

  • There may only be column references in the row constructor on the IN predicate's left hand side.

  • There must be more than one row constructor on the IN predicate's right hand side.

  • Row constructors on the IN predicate's right hand side must contain only runtime constants, which are either literals or local column references that are bound to constants during execution.

Compared to similar queries executed before MySQL 5.7.3, EXPLAIN output for applicable queries changes from full table or index scan to range scan. Changes are also visible by checking the values of theHandler_read_firstHandler_read_key, and Handler_read_next status variables.


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • NSMutableAttributedString繼承於NSAttributedString(帶屬性的字元串)能夠簡單快速實現富文本的效果;不多說直接上效果圖和代碼,通俗易懂: (一)效果圖: (二)代碼: 1 UILabel *testLabel = [[UILabel alloc]initWit
  • 5. 取消請求 可以通過請求的setTag()方法給請求設置TAG,需要取消這些請求時,用請求隊列的cancelAll()方法取消帶有特定TAG的請求。 為請求設置TAG: stringRequest.setTag("xyz"); jsonObjectRequest.setTag("xyz"); p
  • iOS在現代電腦語言中,面向對象是非常重要的特性,Swift語言也提供了面向對象的支持。而且在Swift語言中,不僅類具有面向對象特性,結構體和枚舉也都具有面向對象特性。 1、Swift中的類和結構體 Swift中的類和結構體定義的語法也是非常相似的。我們可以使用class關鍵詞定義類,下麵我們定
  • UILocalNotification *notification=[[UILocalNotification alloc] init]; if (notification!=nil) { NSDate *now=[NSDate new]; //notification.fireDate=[now
  • 從2月14日開始,上傳程式的同學可能會遇到提示上傳失敗的提示. 並且打開自己的鑰匙串,發現所有的證書全部都顯示此證書簽發者無效. 出現以下情況: Failed to locate or generate matching signing assetsXcode attempted to locate
  • 不知道你有沒有註意,最近的app中越來越多的使用webview了,個人感覺,一方面是因為微信公眾號開發增多的促進,讓很多頁面開發後用到微信上面後,還要唚在公司的app中使用,又加上html5的進一步火熱,可以跨平臺使用,一次開發,可以用在Ios,android客戶端上,這樣,極大的節省了公司的開發成
  • apple提供了CoreData作為數據存儲的一種手段。本人對其他的第三方不來點,喜歡apple的親兒子,原汁原味,就研究學習這個了。本次帶來CoreData相關數據模型關係操作。
  • .NET事務應用原則 1.在同一個資料庫內進行CRUD時,應使用同一個DbConnection對象,且顯式指定DbConnection均為同一個DbTransaction,示例代碼如下: //在同一個DB中操作一個表時,可以不用顯式指定事務,因為單條SQL命令就是一個最小的事務單元 using (D
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...