成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

關于MySQL的SQL優化之覆蓋索引

數據庫 MySQL
利用索引提升SQL的查詢效率是我們經常使用的一個技巧,但是有些時候MySQL給出的執行計劃卻完全出乎我們的意料,我們預想MySQL會通過索引掃描完成查詢,但是MySQL給出的執行計劃卻是通過全表掃描完成查詢的,其中的某些場景我們可以利用覆蓋索引進行優化。

前些天,有個同事跟我說:“我寫了個SQL,SQL很簡單,但是查詢速度很慢,并且針對查詢條件創建了索引,然而索引卻不起作用,你幫我看看有沒有辦法優化?”。

我對他提供的case進行了優化,并將優化過程整理了下來。

我們先來看看優化前的表結構、數據量、SQL、執行計劃、執行時間等。

1. 表結構:

  1. CREATE TABLE `t_order` ( 
  2.  
  3. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
  4.  
  5. `order_code` char(12) NOT NULL
  6.  
  7. `order_amount` decimal(12,2) NOT NULL
  8.  
  9. PRIMARY KEY (`id`), 
  10.  
  11. UNIQUE KEY `uni_order_code` (`order_code`) USING BTREE 
  12.  
  13. ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;  

隱藏了部分不相關字段后,可以看到表足夠簡單, 并且在order_code上創建了唯一性索引uni_order_code。

2. 數據量:316977

這個數據量還是比較小的,不過如果SQL足夠差,一樣會查詢很慢。

3. SQL:

  1. select order_code, order_amount from t_order order by order_code limit 1000; 

哇,SQL足夠簡單,不過有時候越簡單也越難優化。

4. 執行計劃:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t_order ALL NULL NULL NULL NULL 316350 Using filesort

全表掃描、文件排序,注定查詢慢!

那為什么MySQL沒有利用索引(uni_order_code)掃描完成查詢呢?因為MySQL認為這個場景利用索引掃描并非***的結果。我們先來看下執行時間,然后再來分析為什么沒有利用索引掃描。

5. 執行時間:260ms 

 

 

 

的確,執行時間太長了,如果表數據量繼續增長下去,性能會越來越差。

我們來分析下MySQL為什么使用全表掃描、文件排序,而沒有使用索引掃描、利用索引順序:

1. 全表掃描、文件排序:

雖然是全表掃描,但是掃描是順序的(不管機械硬盤還是SSD順序讀寫性能都是高的),并且數據量不是特別大,所以這部分消耗的時間應該不是特別大,主要的消耗應該是在排序上。

2. 利用索引掃描、利用索引順序:

uni_order_code是二級索引,索引上保存了(order_code,id),每掃描一條索引需要根據索引上的id定位(隨機IO)到數據行上讀取order_amount,需要1000次隨機IO才能完成查詢,而機械硬盤隨機IO的效率是極低的(機械硬盤每秒尋址幾百次)。

根據我們自己的分析選擇全表掃描相對更優。如果把limit 1000改成limit 10,則執行計劃會完全不一樣。

既然我們已經知道是因為隨機IO導致無法利用索引,那么有沒有辦法消除隨機IO呢?

有,覆蓋索引。

我們來看看利用覆蓋索引優化后的索引、執行計劃、執行時間。

1. 創建索引:

  1. ALTER TABLE `t_order` 
  2.  
  3. ADD INDEX `idx_ordercode_orderamount` USING BTREE (`order_code` ASC, `order_amount` ASC);  

創建了復合索引idx_ordercode_orderamount(order_code,order_amount),將select的列order_amount也放到索引中。

2. 執行計劃:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t_order index NULL idx_ordercode_
orderamount
42 NULL 1000 Using index

執行計劃顯示查詢會利用覆蓋索引,并且只掃描了1000行數據,查詢的性能應該是非常好的。

3. 執行時間:13ms 

 

 

 

從執行時間來看,SQL的執行時間提升到原來的1/20,已經達到我們的預期。

總結:

覆蓋索引是select的數據列只用從索引中就能夠取得,不必讀取數據行,換句話說查詢列要被所建的索引覆蓋。索引的字段不只包含查詢列,還包含查詢條件、排序等。

要寫出性能很好的SQL不僅需要學習SQL,還要能看懂數據庫執行計劃,了解數據庫執行過程、索引的數據結構等。 

責任編輯:龐桂玉 來源: Mr船長的博客
相關推薦

2021-07-16 23:01:03

SQL索引性能

2010-05-12 11:14:25

MySQL SQL優化

2021-07-26 18:23:23

SQL策略優化

2023-09-22 10:05:32

2009-10-20 18:32:25

Oracle 10g

2011-07-11 15:28:19

MySQL索引優化

2017-09-04 16:03:46

MySQLMySQL索引索引

2020-02-14 18:10:40

MySQL索引數據庫

2018-10-19 12:47:35

MySQLSQL優化數據庫

2010-07-07 11:28:12

SQL Server索

2010-07-19 15:50:53

SQL Server索

2020-10-19 19:45:58

MySQL數據庫優化

2024-03-06 20:00:50

MySQL優化器索引

2015-10-30 15:55:43

MySQL

2017-07-25 12:07:14

MySQL索引SQL

2021-05-09 09:57:26

MySQL數據庫索引

2017-08-25 15:28:20

Oracle性能優化虛擬索引

2010-05-14 17:56:16

SQL優化索引

2018-06-07 08:54:01

MySQL性能優化索引

2020-01-22 16:36:52

MYSQL開源數據庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩高清中文字幕 | 一区在线免费视频 | av片在线观看网站 | 成人在线观看免费 | 亚洲一区二区电影网 | 亚洲国产精品成人无久久精品 | 国产一区二区三区免费 | 欧美精品久久久 | a视频在线 | 国产性网 | 日本黄色不卡视频 | 欧洲亚洲精品久久久久 | 国产精品射 | 毛片免费在线 | 男女午夜免费视频 | 99亚洲精品 | 一区二区三区四区免费观看 | 久久中文视频 | 综合婷婷 | 毛片高清 | 亚洲综合色视频在线观看 | 成人午夜电影网 | 天堂va在线 | 日韩福利| 欧美激情视频一区二区三区在线播放 | 亚洲高清视频一区二区 | 粉嫩av在线| 在线精品一区 | 精品成人免费一区二区在线播放 | 亚洲精品一区二区网址 | 欧美三区 | 91久久久久久久 | 亚洲欧美激情精品一区二区 | 91精品国产91综合久久蜜臀 | 最新国产精品精品视频 | 久久国产精品精品国产色婷婷 | 国产欧美久久一区二区三区 | 欧美电影大全 | 九九色综合 | 美女天堂| 免费看黄色小视频 |