這篇文章主要介紹了記一次因線上mysql優化器誤判引起慢查詢事件的相關資料以及最終的解決方案,分享給大家,希望能夠給大家一點啟發。
前言:
收到瘋狂的慢查詢及請求超時報警,透過metrics分析出來自mysql請求的異常,cli —> show proceslist 看到很多慢查詢。 先前該sql是沒有的,後面因為資料量的成長才出現了這問題。 雖然feeds表大到一億,但因為feeds流資訊有近期熱的特徵,所以不是因為 innodb_buffer_pool_size 低效率引起的io頻繁。 後來經過進一步explain執行計劃分析得出了原因,mysql查詢優化器選擇了他認為高效的索引。
mysql查詢優化器大多數情況是可靠的! 但是你的sql語言含有多個索引時就要注意了,往往最後的結果令人有些徬徨了。因為mysql同一個sql只能使用一個索引,那麼選哪一個呢? 在資料量小時候,mysql優化器會把主鍵索引後置,優先使用 index和unique 。 當你達到一個資料量級後,又因為你的查詢操作有 in ,那麼mysql查詢優化器很可能會選用主鍵的 !
記住一句話,mysql查詢優化是基於檢索成本考慮,而不是基於時間成本考慮。 優化器是根據現有的資料狀態來推算代價,而不是真的去執行一遍sql.
所以,mysql優化器並不是每次都可以達到優化的效果的。 它並不能準確預估代價,如果要準確得到走各個索引的代價就要去真的執行一遍才能知道,所以代價分析只是做了一個預估,既然是預估那麼就有誤判。
我們這裡說的表是feed資訊流表,我們知道feeds資訊流表存取不僅頻繁,而且資料量也很大。 但是這個表的資料結構很簡單,索引也簡單. 總共就兩個索引,一個是主鍵索引, 一個是unique唯一鍵索引。
如下,該表的量級已經到億級別了,因為有足夠多的cache前頂,又因為這樣那樣的原因,所以沒來的及做分庫分錶。
問題是這樣的, 當資料量級不到一個億的時候,mysql優化器選擇使用index索引, 當資料量級超過一個億個後,mysql查詢優化器選擇使用主鍵索引了。 這樣帶來的問題就是 查詢速度太慢。
這是正常情況下:
mysql> explain SELECT * FROM `feed` WHERE user_id IN (116537309,116709093,116709377) AND cid IN (1001,1005,1054,1092,1093,1095) AND id <= 128384713 ORDER BY id DESC LIMIT 0, 11 \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: feed partitions: NULL type: range possible_keys: PRIMARY,feed_user_target key: feed_user_target key_len: 6 ref: NULL rows: 18 filtered: 50.00 Extra: Using where; Using index; Using filesort 1 row in set, 1 warning (0.00 sec)
#同樣的sql語句,在資料量有較大變化後,mysql查詢最佳化器對索引的選擇也有了變化。
mysql> explain SELECT * FROM `feed` WHERE user_id IN (116537309,116709093,116709377) AND cid IN (1001,1005,1054,1092,1093,1095) AND id <= 128384713 ORDER BY id DESC LIMIT 0, 11 \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: feed type: range possible_keys: PRIMARY,feed_user_target key: PRIMARY key_len: 4 ref: NULL rows: 11873197 Extra: Using where 1 row in set (0.00 sec)
那麼解決方法就是使用 force index,強制查詢最佳化器使用我們給的index 。 我在這裡是python開發環境,常見的python orm都有force index,ignore index,user index 參數的。
explain SELECT * FROM `feed` force index (feed_user_target) WHERE user_id IN (116537309,116709093,116709377) ...
那我們該怎麼預防這種 因為資料的增進,mysql優化器選擇了一個低效索引的問題呢?
針對這個問題請教了幾個廠的dba,得到的答案和我們的方法是一樣的。 都是只能透過後期的慢查詢來發現問題,然後在sql語句中指定force index來解決索引問題。 另外,在系統上線初期就會做這類問題的規避,但往往業務開發人員初期都會配合dba們的審查工作,但後期為了省事,或者說自以為是認為沒有問題,所以造成了 mysql查詢事故。
我自己對於mysql優化器選擇索引規則一知半解的,後面準備花時間好好研究下規則
以上就是記一次因線上mysql優化器誤判引起慢查詢事件的分享的內容,更多相關內容請關注PHP中文網(www.php.cn)!

MySQL使用的是GPL許可證。 1)GPL許可證允許自由使用、修改和分發MySQL,但修改後的分發需遵循GPL。 2)商業許可證可避免公開修改,適合需要保密的商業應用。

選擇InnoDB而不是MyISAM的情況包括:1)需要事務支持,2)高並發環境,3)需要高數據一致性;反之,選擇MyISAM的情況包括:1)主要是讀操作,2)不需要事務支持。 InnoDB適合需要高數據一致性和事務處理的應用,如電商平台,而MyISAM適合讀密集型且無需事務的應用,如博客系統。

在MySQL中,外鍵的作用是建立表與表之間的關係,確保數據的一致性和完整性。外鍵通過引用完整性檢查和級聯操作維護數據的有效性,使用時需注意性能優化和避免常見錯誤。

MySQL中有四種主要的索引類型:B-Tree索引、哈希索引、全文索引和空間索引。 1.B-Tree索引適用於範圍查詢、排序和分組,適合在employees表的name列上創建。 2.哈希索引適用於等值查詢,適合在MEMORY存儲引擎的hash_table表的id列上創建。 3.全文索引用於文本搜索,適合在articles表的content列上創建。 4.空間索引用於地理空間查詢,適合在locations表的geom列上創建。

toCreateAnIndexinMysql,usethecReateIndexStatement.1)forasingLecolumn,使用“ createIndexIdx_lastNameEnemployees(lastName); 2)foracompositeIndex,使用“ createIndexIndexIndexIndexIndexDx_nameOmplayees(lastName,firstName,firstName);” 3)forauniqe instex,creationexexexexex,

MySQL和SQLite的主要區別在於設計理念和使用場景:1.MySQL適用於大型應用和企業級解決方案,支持高性能和高並發;2.SQLite適合移動應用和桌面軟件,輕量級且易於嵌入。

MySQL中的索引是數據庫表中一列或多列的有序結構,用於加速數據檢索。 1)索引通過減少掃描數據量提升查詢速度。 2)B-Tree索引利用平衡樹結構,適合範圍查詢和排序。 3)創建索引使用CREATEINDEX語句,如CREATEINDEXidx_customer_idONorders(customer_id)。 4)複合索引可優化多列查詢,如CREATEINDEXidx_customer_orderONorders(customer_id,order_date)。 5)使用EXPLAIN分析查詢計劃,避

在MySQL中使用事務可以確保數據一致性。 1)通過STARTTRANSACTION開始事務,執行SQL操作後用COMMIT提交或ROLLBACK回滾。 2)使用SAVEPOINT可以設置保存點,允許部分回滾。 3)性能優化建議包括縮短事務時間、避免大規模查詢和合理使用隔離級別。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Linux新版
SublimeText3 Linux最新版

記事本++7.3.1
好用且免費的程式碼編輯器

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中