中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何解決工作中遇到的SQL優化

發布時間:2021-09-13 11:26:50 來源:億速云 閱讀:150 作者:柒染 欄目:大數據

這期內容當中小編將會給大家帶來有關如何解決工作中遇到的SQL優化,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

-- 示例表
CREATE TABLE `employees` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(24) NOT NULL DEFAULT '' COMMENT '姓名',
  `age` int(20) NOT NULL DEFAULT '0' COMMENT '年齡',
  `position` varchar(20) NOT NULL DEFAULT '' COMMENT '職位',
  `hire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '入職時間',
  PRIMARY KEY (`id`),
  KEY `idx_name_age_position` (`name`,`age`,`position`) USING BTREE,
  KEY `idx_age` (`age`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=136326 DEFAULT CHARSET=utf8 COMMENT='員工表'

Order by與Group by優化

EXPLAIN select * from employees WHERE name='LiLei' and position='dev' order by age;

如何解決工作中遇到的SQL優化

利用最左前綴法則:中間字段不能斷,因此查詢用到了name索引,從key_len=74也能看出,age索引列用在排序的過程中,因為Extra字段里沒有using filesort。

EXPLAIN select * from employees WHERE name='LiLei'  order by position;

如何解決工作中遇到的SQL優化 從explain的執行結果來看:key_len=74, 查詢使用name索引,由于用了position進行排序,跳過了age,出現了Using filesort。

EXPLAIN select * from employees WHERE name='LiLei'  order by age,position;

如何解決工作中遇到的SQL優化

查找只用到了name索引,age和position用于排序,無Using filesort。

EXPLAIN select * from employees WHERE name='LiLei'  order by position,age;

如何解決工作中遇到的SQL優化

和上一個case不同的是,Extra中出現了Using filesort,因為索引的創建順序為name,age,position,但是排序的時候age和position顛倒了位置。

EXPLAIN select * from employees WHERE name='LiLei'  order by age asc, position desc;

如何解決工作中遇到的SQL優化

雖然排序的字段和聯合索引順序是一樣的,且order by是默認升序,這里position desc是降序,導致與索引的排序方式不同,從而產生Using filesort。Mysql8以上版本有降序索引可以支持該種查詢方式。

EXPLAIN select * from employees WHERE name in('LiLei', 'zhuge')  order by age, position ;

如何解決工作中遇到的SQL優化

對于排序來說,多個相等條件也是范圍查詢。

EXPLAIN select * from employees WHERE name > 'a' order by name;

如何解決工作中遇到的SQL優化

可以用覆蓋索引優化

EXPLAIN select name,age,position from employees WHERE name > 'a' order by name;

如何解決工作中遇到的SQL優化

filesort排序

EXPLAIN select * from employees where name='LiLei' order by position;

如何解決工作中遇到的SQL優化

查看這條sql對應trace結果(只展示排序部分):

set session optimizer_trace="enabled=on",end_markers_in_json=on; ‐‐開啟trace
select * from employees where name = 'LiLei' order by position;
select * from information_schema.OPTIMIZER_TRACE;

{
      "join_execution": {  --sql執行階段
        "select#": 1,
        "steps": [
          {
            "filesort_information": [
              {
                "direction": "asc",
                "table": "`employees`",
                "field": "position"
              }
            ] /* filesort_information */,
            "filesort_priority_queue_optimization": {
              "usable": false,
              "cause": "not applicable (no LIMIT)"
            } /* filesort_priority_queue_optimization */,
            "filesort_execution": [
            ] /* filesort_execution */,
            "filesort_summary": {  --文件排序信息
              "rows": 1,  --預計掃描行數
              "examined_rows": 1,  --參與排序的行
              "number_of_tmp_files": 0, --使用臨時文件的個數,這個值為0代表全部使用sort_buffer內存排序,否則使用磁盤文件排序
              "sort_buffer_size": 200704,  --排序緩存的大小
              "sort_mode": "<sort_key, additional_fields>"  --排序方式,這里用的單路排序
            } /* filesort_summary */
          }
        ] /* steps */
      } /* join_execution */
    }

修改max_length_for_sort_data=10

set max_length_for_sort_data = 10;  --employees表所有字段長度總和肯定大于10字節
select * from employees where name = 'LiLei' order by position;
select * from information_schema.OPTIMIZER_TRACE;

{
      "join_execution": {
        "select#": 1,
        "steps": [
          {
            "filesort_information": [
              {
                "direction": "asc",
                "table": "`employees`",
                "field": "position"
              }
            ] /* filesort_information */,
            "filesort_priority_queue_optimization": {
              "usable": false,
              "cause": "not applicable (no LIMIT)"
            } /* filesort_priority_queue_optimization */,
            "filesort_execution": [
            ] /* filesort_execution */,
            "filesort_summary": {
              "rows": 1,
              "examined_rows": 1,
              "number_of_tmp_files": 0,
              "sort_buffer_size": 53248,
              "sort_mode": "<sort_key, rowid>"  --排序方式為雙路排序
            } /* filesort_summary */
          }
        ] /* steps */
      } /* join_execution */
    }

對比這兩個排序模式,單路排序會把所有的需要查詢的字段數據都放到sort_buffer中,而雙路排序只會把主鍵id和需要排序的字段放到sort_buffer中進行排序,然后再通過主鍵id 回到原表 查詢需要的字段數據。MySQL通過max_length_for_sort_data這個參數來控制排序,在不同場景下使用不同的排序模式,從而提升排序效率。

優化總結

  • Mysql支持兩種方式的排序filesort和index,using index是指Mysql掃描索引本身完成排序。index效率高,filesort效率低。

  • order by滿足兩種情況會使用using index。 order by語句使用索引最左前列。 使用where子句和order by子句 條件列組合滿足索引最左前列。

  • 盡量在索引列上完成排序,遵循索引建立(索引創建的順序)時候的最左前綴法則。

  • 如果order by 的條件不在索引列上,就會產生using filesort。


上述就是小編為大家分享的如何解決工作中遇到的SQL優化了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

凤城市| 乐平市| 高青县| 灵寿县| 天镇县| 句容市| 乐亭县| 巴彦淖尔市| 昭觉县| 平原县| 嘉禾县| 扶余县| 上栗县| 商南县| 贵溪市| 元朗区| 临武县| 交城县| 武穴市| 沁源县| 克东县| 大英县| 盐山县| 禹城市| 佛冈县| 宁晋县| 文水县| 铜陵市| 都昌县| 瓦房店市| 宿迁市| 蕉岭县| 上栗县| 沁源县| 遵化市| 永靖县| 平利县| 扶沟县| 蓬莱市| 临泽县| 宜兴市|