最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL范圍查詢優(yōu)化的場景實例詳解

 更新時間:2022年06月10日 15:39:45   作者:lfwh  
范圍訪問方法使用單一索引去檢索表中的數(shù)據(jù)包含一個或者多個索引值的行記錄,下面這篇文章主要給大家介紹了關于MySQL范圍查詢優(yōu)化的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

思考題

假設有一張訂單表 order,主要包含了主鍵訂單編碼 order_no、訂單狀態(tài) status、提交時間 create_time 等列,并且創(chuàng)建了 status 列索引和 create_time 列索引。此時通過創(chuàng)建時間降序獲取狀態(tài)為 1 的訂單編碼,以下是具體實現(xiàn)代碼:

select order_no from order where status =1 order by create_time desc;

你知道其中的問題所在嗎?我們又該如何優(yōu)化?

解析

status和create_time單獨建索引,在查詢時只會遍歷status索引對數(shù)據(jù)進行過濾,不會用到create_time列索引,將符合條件的數(shù)據(jù)返回到server層,在server對數(shù)據(jù)通過快排算法進行排序,Extra列會出現(xiàn)file sort;

應該利用索引的有序性,在status和create_time列建立聯(lián)合索引,這樣根據(jù)status過濾后的數(shù)據(jù)就是按照create_time排好序的,避免在server層排序

對的,為了避免文件排序的發(fā)生。因為查詢時我們只能用到status索引,如果要對create_time進行排序,則需要使用文件排序filesort。

filesort是通過相應的排序算法將取得的數(shù)據(jù)在內存中進行排序,如果內存不夠則會使用磁盤文件作為輔助。雖然在一些場景中,filesort并不是特別消耗性能,但是我們可以避免filesort就盡量避免。

阿里巴巴MySQL規(guī)范

【推薦】 如果有 order by 的場景,請注意利用索引的有序性。 order by 最后的字段是組合索引的一部分,并且放在索引組合順序的最后,避免出現(xiàn) file_sort 的情況,影響查詢性能。

正例: where a=? and b=? order by c; 索引: a_b_c

反例: 索引如果存在范圍查詢, 那么索引有序性無法利用,如: WHERE a>10 ORDER BY b; 索引 a_b 無 法排序

范圍查詢-基礎

講聯(lián)合索引,一定要扯最左匹配!

最左匹配 所謂最左原則指的就是如果你的 SQL 語句中用到了聯(lián)合索引中的最左邊的索引,那么這條 SQL 語句就可以利用這個聯(lián)合索引去進行匹配,值得注意的是,當遇到范圍查詢(>、<、between、like)就會停止匹配。 假設,我們對(a,b)字段建立一個索引,也就是說,你where后條件為

a = 1
a = 1 and b = 2

是可以匹配索引的。但是要注意的是~你執(zhí)行

b= 2 and a =1

也是能匹配到索引的,因為Mysql有優(yōu)化器會自動調整a,b的順序與索引順序一致。 相反的,你執(zhí)行

b = 2

就匹配不到索引了。 而你對(a,b,c,d)建立索引,where后條件為

a = 1 and b = 2 and c > 3 and d = 4

那么,a,b,c三個字段能用到索引,而d就匹配不到。因為遇到了范圍查詢!

場景一: a = 1 and b = 2 and c = 3

如果sql為

SELECT * FROM table WHERE a = 1 and b = 2 and c = 3; 

如何建立索引?

如果此題回答為對(a,b,c)建立索引,那都可以回去等通知了。

此題正確答法是,(a,b,c)或者(c,b,a)或者(b,a,c)都可以,重點要的是將區(qū)分度高的字段放在前面,區(qū)分度低的字段放后面。像性別、狀態(tài)這種字段區(qū)分度就很低,我們一般放后面。

例如假設區(qū)分度由大到小為b,a,c。那么我們就對(b,a,c)建立索引。在執(zhí)行sql的時候,優(yōu)化器會 幫我們調整where后a,b,c的順序,讓我們用上索引。

阿里巴巴Java 開發(fā)手冊

【強制】 在 varchar 字段上建立索引時,必須指定索引長度,沒必要對全字段建立索引,根據(jù) 實際文本區(qū)分度決定索引長度。

說明: 索引的長度與區(qū)分度是一對矛盾體,一般對字符串類型數(shù)據(jù),長度為 20 的索引,區(qū)分度會高達 90%以上,可以使用 count(distinct left(列名, 索引長度))/count(*)的區(qū)分度來確定。

場景二: a > 1 and b = 2

如果sql為

SELECT * FROM table WHERE a > 1 and b = 2; 

如何建立索引?

如果此題回答為對(a,b)建立索引,那都可以回去等通知了。

此題正確答法是,對(b,a)建立索引。如果你建立的是(a,b)索引,那么只有a字段能用得上索引,畢竟最左匹配原則遇到范圍查詢就停止匹配。

如果對(b,a)建立索引那么兩個字段都能用上,優(yōu)化器會幫我們調整where后a,b的順序,讓我們用上索引。

場景三:a > 1 and b = 2 and c > 3

如果sql為

SELECT * FROM `table` WHERE a > 1 and b = 2 and c > 3; 

如何建立索引? 此題回答也是不一定,(b,a)或者(b,c)都可以,要結合具體情況具體分析。

拓展一下

SELECT * FROM `table` WHERE a = 1 and b = 2 and c > 3; 

怎么建索引?嗯,大家一定都懂了!

場景四: a > 1 ORDER BY b

SELECT * FROM `table` WHERE a = 1 ORDER BY b;

如何建立索引? 這還需要想?一看就是對(a,b)建索引,當a = 1的時候,b相對有序,可以避免再次排序! 那么

SELECT * FROM `table` WHERE a > 1 ORDER BY b; 

如何建立索引?

對(a)建立索引,因為a的值是一個范圍,這個范圍內b值是無序的,沒有必要對(a,b)建立索引。

拓展一下

SELECT * FROM `table` WHERE a = 1 AND b = 2 AND c > 3 ORDER BY c;

怎么建索引?

場景五: a IN (1,2,3) and b > 1

SELECT * FROM `table` WHERE a IN (1,2,3) and b > 1; 

如何建立索引?

還是對(a,b)建立索引,因為IN在這里可以視為等值引用,不會中止索引匹配,所以還是(a,b)!

拓展一下

SELECT * FROM `table` WHERE a = 1 AND b IN (1,2,3) AND c > 3 ORDER BY c;

如何建立索引?此時c排序是用不到索引的。

總結

盡可能將范圍查詢轉換成“等值”查詢,如 “a>1 and a<5 and b>10” 可以寫成“a in (1,2,3,4,5) and b > 10”,然后設置索引為 idx(a,b)。

將“等值”條件放在最左邊,按最左匹配就可以命中索引。

參考鏈接1

參考鏈接2

到此這篇關于MySQL范圍查詢優(yōu)化的文章就介紹到這了,更多相關MySQL范圍查詢優(yōu)化內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • MySQL中Like概念及用法講解

    MySQL中Like概念及用法講解

    在本篇文章里小編給大家整理的是一篇關于MySQL中Like概念及用法講解內容,有興趣的朋友們可以學習參考下。
    2021-02-02
  • MySQL Limit性能優(yōu)化及分頁數(shù)據(jù)性能優(yōu)化詳解

    MySQL Limit性能優(yōu)化及分頁數(shù)據(jù)性能優(yōu)化詳解

    今天小編就為大家分享一篇關于MySQL Limit性能優(yōu)化及分頁數(shù)據(jù)性能優(yōu)化詳解,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 深入SQL Server中char、varchar、text和nchar、nvarchar、ntext的區(qū)別詳解

    深入SQL Server中char、varchar、text和nchar、nvarchar、ntext的區(qū)別詳

    本篇文章是對char、varchar、text和nchar、nvarchar、ntext的區(qū)別進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • MySQL8的主要目錄結構解讀

    MySQL8的主要目錄結構解讀

    這篇文章主要介紹了MySQL8的主要目錄結構,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 聽說mysql中的join很慢?是你用的姿勢不對吧

    聽說mysql中的join很慢?是你用的姿勢不對吧

    這篇文章主要介紹了聽說mysql中的join很慢?是你用的姿勢不對吧,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • MySQL索引失效之隱式轉換的問題

    MySQL索引失效之隱式轉換的問題

    本文主要介紹了MySQL索引失效之隱式轉換的問題,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • MySQL中的undo日志

    MySQL中的undo日志

    這篇文章主要介紹了MySQL中的undo日志的相關資料,幫助大家更好的理解和學習MySQL的相關知識,感興趣的朋友可以了解下
    2020-11-11
  • python中的mysql數(shù)據(jù)庫LIKE操作符詳解

    python中的mysql數(shù)據(jù)庫LIKE操作符詳解

    LIKE操作符用于在WHERE子句中搜索列中的指定模式,like操作符的語法在文章開頭也給大家提到,通過兩種示例代碼給大家介紹python中的mysql數(shù)據(jù)庫LIKE操作符知識,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • MySQL多表查詢、事務與索引的實踐與應用操作

    MySQL多表查詢、事務與索引的實踐與應用操作

    本文圍繞MySQL數(shù)據(jù)庫操作展開,通過構建部門與員工管理、餐飲業(yè)務相關的數(shù)據(jù)庫表,并填充測試數(shù)據(jù),系統(tǒng)地闡述了多表查詢的多種方式,包括內連接、外連接和不同類型的子查詢,同時介紹了事務的處理以及索引的創(chuàng)建、查詢和刪除操作,感興趣的朋友一起看看吧
    2025-04-04
  • MySQL基礎學習之字符集的應用

    MySQL基礎學習之字符集的應用

    這篇文章主要為大家詳細介紹了MySQL中字符集的相關使用,例如字符集的查詢與修改和比較規(guī)則等,文中的示例代碼講解詳細,需要的可以參考一下
    2023-05-05

最新評論

盘山县| 交城县| 宁乡县| 武穴市| 宜兰县| 达日县| 马关县| 崇左市| 枣庄市| 安塞县| 天津市| 怀远县| 射阳县| 平邑县| 海城市| 肇东市| 广饶县| 西畴县| 建平县| 吉安县| 璧山县| 香格里拉县| 玉环县| 肃宁县| 新疆| 南昌县| 平昌县| 小金县| 改则县| 准格尔旗| 新野县| 大同市| 临江市| 隆尧县| 林周县| 沂水县| 灵石县| 鄂温| 高邑县| 靖宇县| 峨山|