<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
從系統設計角度看,一個系統從設計搭建到資料逐步增長,SQL 執行效率可能會出現劣化,為繼續支撐業務發展,我們需要對慢 SQL 進行分析和優化,嚴峻的情況下甚至需要對整個系統進行重構。所以我們往往需要在系統設計前對業務進行充分調研、遵守系統設計規範,在系統執行時定期結合當前業務發展情況進行系統瓶頸的分析。
從資料庫角度看,每個 SQL 執行都需要消耗一定 I/O 資源,SQL 執行的快慢,決定了資源被佔用時間的長短。假如有一條慢 SQL 佔用了 30%的資源共計 1 分鐘。那麼在這 1 分鐘時間內,其他 SQL 能夠分配的資源總量就是 70%,如此迴圈,當資源分配完的時候,所有新的 SQL 執行將會排隊等待。所以往往一條慢 SQL 會影響到整個業務。
本文僅討論 MySQL-InnoDB 的情況。
SQL 語句執行效率的主要因素
select * from table_demo where type = ? limit ?,?;
優化方式一:偏移 id
lastId = 0 or min(id) do { select * from table_demo where type = ? and id >{#lastId} limit ?; lastId = max(id) } while (isNotEmpty)
優化方式二:分段查詢
該方式較方式一的優點在於可並行查詢,每個分段查詢互不依賴;較方式一的缺點在於較依賴資料的連續性,若資料過於分散,代價較高。
minId = min(id) maxId = max(id) for(int i = minId; i<= maxId; i+=pageSize){ select * from table_demo where type = ? and id between i and i+ pageSize; }
優化 GROUP BY
提高 GROUP BY 語句的效率, 可以通過將不需要的記錄在 GROUP BY 之前過濾掉.下面兩個查詢返回相同結果但第二個明顯就快了許多。
低效:
select job , avg(sal) from table_demo group by job having job = ‘manager'
高效:
select job , avg(sal) from table_demo where job = ‘manager' group by job
範圍查詢
聯合索引中如果有某個列存在範圍(大於小於)查詢,其右邊的列是否還有意義?
explain select count(1) from statement where org_code='1012' and trade_date_time >= '2019-05-01 00:00:00' and trade_date_time<='2020-05-01 00:00:00' explain select * from statement where org_code='1012' and trade_date_time >= '2019-05-01 00:00:00' and trade_date_time<='2020-05-01 00:00:00' limit 0, 100 explain select * from statement where org_code='1012' and trade_date_time >= '2019-05-01 00:00:00' and trade_date_time<='2020-05-01 00:00:00'
使用單鍵索引 trade_date_time 的情況下
使用聯合索引 trade_date_time, org_code -聯合索引 trade_date_time, org_code 底層結構推導如下:
以查詢 trade_date_time >='2019-05-01' and trade_date_time <='2020-05-01' and org_code='1020'為例:
小結:對於該 case, 索引效果[org_code,trade_date_time] > [trade_date_time, org_code]>[trade_date_time]。實際業務場景中,檢索條件中 trade_date_time 基本上肯定會出現,但 org_code 卻不一定,故索引的設計還需要結合實際業務需求。
優化 Order by
索引:
KEY `idx_account_trade_date_time` (`account_number`,`trade_date_time`), KEY `idx_trade_date_times` (`trade_date_time`) KEY `idx_createtime` (`create_time`),
慢 SQL:
SELECT id,....,creator,modifier,create_time,update_time FROM statement WHERE (account_number = 'XXX' AND create_time >= '2022-04-24 06:03:44' AND create_time <= '2022-04-24 08:03:44' AND dc_flag = 'C') ORDER BY trade_date_time DESC,id DESC LIMIT 0,1000;
優化前:SQL 執行超時被 kill 了
SELECT id,....,creator,modifier,create_time,update_time FROM statement WHERE (account_number = 'XXX' AND create_time >= '2022-04-24 06:03:44' AND create_time <= '2022-04-24 08:03:44' AND dc_flag = 'C') ORDER BY create_time DESC,id DESC LIMIT 0,1000;
優化後:執行總行數為:6 行,耗時 34ms。
MySQL使不使用索引與所查列無關,只與索引本身,where條件,order by 欄位,group by 欄位有關。索引的作用一個是查詢,一個是排序。
業務拆分
select * from order where status='S' and update_time < now-5min limit 500
拆分優化:
隨著業務資料的增長 status='S'的資料基本佔據資料的 90%以上,此時該條件無法走索引。我們可以結合業務特徵,對資料獲取按日期進行拆分。
date = now; minDate = now - 10 days while(date > minDate) { select * from order where order_date={#date} and status='S' and update_time < now-5min limit 500 date = data + 1 }
SQL 檢查狀態及分數計算邏輯
MySQL 邏輯架構圖:
優點
提高查詢語句的執行效率,減少 IO 操作的次數
建立唯一性索引,可以保證資料庫表中每一行資料的唯一性
加了索引的列會進行排序,在使用分組和排序子句進行查詢時,可以顯著減少查詢中分組和排序的時間
缺點
索引需要佔物理空間
建立索引和維護索引要耗費時間,這種時間隨著資料量的增加而增加
當對錶中的資料進行增刪改查時,索引也要動態的維護,這樣就降低了資料的更新效率
主鍵索引
普通索引
組合索引
索引頁結構
索引頁由七部分組成,其中 Infimum 和 Supremum 也屬於記錄,只不過是虛擬記錄,這裡為了與使用者記錄區分開,還是決定將兩者拆開。
資料行格式:
MySQL 有 4 種儲存格式:
Dynamic 行儲存格式下,對於處理行溢位(當一個欄位儲存長度過大時,會發生行溢位)時,僅存放溢位頁記憶體地址。
哪些情況適合建索引
哪些情況下不需要使用索引
例如有一張表 user,主鍵 id,普通欄位 age,為 age 建立非聚集索引,有一條查詢語句 select* user from table where age > 18;(注意查詢語句中的結果是*)
在 MySQL5.5 以及之前的版本中如何查詢呢?先通過非聚集索引查詢到 age>18 的第一條資料,獲取到了主鍵 id;然後根據非聚集索引中的葉子節點儲存的主鍵 id 去聚集索引中查詢行資料;根據 age>18 的資料條數每次查詢聚集索引,這個過程叫做回表。
上述的步驟有什麼缺點呢?如何 age>18 的資料非常多,那麼每次回表都需要經過 3 次 IO(假設 B+樹的高度是 3),那麼會導致查詢效率過低。
在 MySQL5.6 時針對上述問題進行了優化,優化器先查詢到 age>3 的所有資料的主鍵 id,對所有主鍵的 id 進行排序,排序的結果快取到 read_rnd_buffer,然後通過排好序的主鍵在聚簇索引中進行查詢。
如果兩個主鍵的範圍相近,在同一個資料頁中就可以之間按照順序獲取,那麼磁碟 io 的過程將會大大降低。這個優化的過程就叫做 Multi Range Read(MRR) 多返回查詢。
假設有索引(name, age), 執行 SQL: select * from tuser where name like '張%' and age=10;
MySQL 5.6 以後, 儲存引擎根據(name,age)聯合索引,找到,由於聯合索引中包含列,所以儲存引擎直接在聯合索引裡按照age=10
過濾。按照過濾後的資料再一一進行回表掃描。
索引下推使用條件
range
、 ref
、 eq_ref
、ref_or_null
存取方法;InnoDB
和 MyISAM
儲存引擎及其分割區表;索引下推的目的是為了減少回表次數,也就是要減少 IO 操作。對於的聚簇索引來說,資料和索引是在一起的,不存在回表這一說。
思考:
拋開資料庫硬體層面,資料庫表設計、索引設計、業務程式碼邏輯、分庫分表策略、資料歸檔策略都對 SQL 執行效率有影響,我們只有在整個設計、開發、運維階段保持高度敏感、追求極致,才能讓我們系統的可用性、伸縮性不會隨著業務增長而劣化。
到此這篇關於慢SQL分析與優化的文章就介紹到這了,更多相關慢SQL分析優化內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
參考資料
https://help.aliyun.com/document_detail/311122.html
https://blog.csdn.net/qq_32099833/article/details/123150701
https://www.cnblogs.com/tufujie/p/9413852.html
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45