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

歡迎訪問 生活随笔!

生活随笔

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

数据库

Mysql优化(三):优化order by

發布時間:2023/12/3 数据库 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mysql优化(三):优化order by 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

MySQL中的兩種排序方式

  • .通過有序索引順序掃描直接返回有序數據
    因為索引的結構是B+樹,索引中的數據是按照一定順序進行排列的,所以在排序查詢中如果能利用索引,就能避免額外的排序操作。EXPLAIN分析查詢時,Extra顯示為Using index。MySQL會結合SQL中的where、order by中的字段去選擇索引。
  • .Filesort排序即對返回的數據進行排序
    所有不是通過索引直接返回排序結果的操作都是Filesort排序,也就是說進行了額外的排序操作。EXPLAIN分析查詢時,Extra顯示為Using filesort。
  • 無法使用索引排序的情況

    首先要注意:

    MySQL一次查詢只能使用一個索引,如果要對多個字段使用索引,建立復合索引。

    注:下列key指代索引,key_part1、key_part2…指代索引中的順序字段

  • 排序字段在不同的索引中,無法使用索引排序:
  • SELECT * FROM t1 ORDER BY key1_part1, key2_part1;
  • 對關鍵字的非連續元素使用ORDER BY,order by 使用索引除了前導列為常量時可以不滿足最左前綴原則,其他時候都需要滿足最左前綴原則
  • //跳過了key_part1,不滿足最左前綴不使用索引 SELECT * FROM t1 ORDER BY key_part2;//前導列為常量,此時可以不滿足最左前綴,使用索引 SELECT * FROM t1 WHERE key_part1=常量 ORDER BY key_part2;
  • 混合ASC和DESC:
  • SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC
  • 用于查詢行的索引與ORDER BY中所使用的索引不相同
  • SELECT * FROM t1 WHERE key2=constant ORDER BY key1;
  • 有不同的ORDER BY和GROUP BY表達式。
  • SELECT * FROM t1 WHERE key_part1=constant ORDER BY key_part2 group by key_part3;

    通過B+Tree結構判斷索引是否能用于排序

    索引是B+Tree的結構,能否使用某個索引來避免排序可以通過數據在B+Tree中的是否有序判斷,下文有具體例子。

    InnoDB的聚簇索引結構如下:

    由此可知道,聚簇索引可以用于主鍵的排序,即order by 主鍵。

    InnoDB的二級索引結構如下:

    (1)二級索引的葉節點并不包含行記錄的全部數據,僅包含索引中的所有鍵和一個用于查找對應行記錄的主鍵值。(非葉子節點不包含主鍵

    (2)Innodb二級索引,索引列值全相同的情況下,節點按主鍵值排序。

    (3)二級索引鍵值的順序和聚簇索引鍵值順序通常不同,所以二級索引做范圍查詢讀取記錄的性能通常不如聚簇索引高效查詢的列不存在二級索引時需要回表,回表操作會有大量的隨機IO)。

    是否使用索引排序取決于使用索引的成本

    在滿足了使用索引排序的條件(上文提及不可用索引排序的情況)的前提下,是否使用索引、使用哪個索引取決于使用索引的成本

    設有表 t(id, create_at),主鍵為id,同時有索引 index(create_at)。不同查詢索引 index(create_at) 的使用情況:
    (1)SELECT id FROM t WHERE create_at='2019年10月15日' ORDER BY id 和 SELECT create_at FROM t WHERE create_at='2019年10月15日' ORDER BY id

    等值查詢,create_at='2019年10月15日'的節點在 索引 index(create_at)結構中按主鍵(id)的順序存儲,因此使用index(create_at)可以避免排序,同時因為覆蓋了所有列,無需回表(Extra 出現 Using index)

    (2)SELECT * FROM t WHERE create_at='2019年10月15日' ORDER BY id

    等值查詢,create_at='2019年10月15日'的節點在 索引 index(create_at)結構中按主鍵(id)的順序存儲,因此使用index(create_at)可以避免排序,雖然需要回表但是通過索引可以過濾大部分的數據,成本低于使用聚簇索引

    (3)SELECT * FROM t WHERE create_at>'2019年10月15日' ORDER BY id

    索引 index(create_at) 不包含所有數據,因此使用 index(create_at)做范圍查詢,每讀取每條記錄都需要回表查詢,會有大量的隨機IO,同時,此時在index(create_at)上id是無序的,所以性能不如直接使用聚簇索引。所以該查詢使用主鍵,通過對主鍵的聚簇索引進行掃描,只需要過濾掉不滿足條件的值而不需要排序

    范圍查詢,需要回表,回表操作會有大量的隨機IO
    (4)SELECT create_at FROM t WHERE create_at>'2019年10月15日' ORDER BY id
    SELECT id FROM t WHERE create_at>'2019年10月15日' ORDER BY id

    此查詢因為索引 index(create_at) 包含所需列,不需要回表查詢,因此使用index(create_at) 可以掃描更少的行,成本低于使用主鍵索引。

    參考

    • 推薦閱讀:淺談InnoDB中的聚簇索引和二級索引[譯]
    • order by 原理以及優化
    • MySQL——優化ORDER BY語句
    • MySQL官網
    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的Mysql优化(三):优化order by的全部內容,希望文章能夠幫你解決所遇到的問題。

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