一個線上問題引起的思考,爲何最左前綴原則?

中秋節前夕,立刻就要準備放假回家去暢遊王者峽谷的小濤收到了報警,某mq消息積壓幾十萬並且正在一直往上漲,看了下依賴的接口和hbase無問題,發現mysql讀寫速度很慢,因而乎看了下mysql機器負載,cpu高達百分之85,使用showprocesslist,查詢當前運行的sql,發現並無很慢的sql,可是發現有以下sql在大量執行,html

可是查詢速度並非很慢,根據訂單號去查了一下該訂單商品,發現此訂單買的商品是買1贈5,可怕的是這我的買了1萬套,對於這樣的場景業務上會存5萬條數據做爲主贈關係,說白了,就是消費這個訂單的消息時,要去查詢5萬次。因爲消費mq超時時間只有3秒,沒等5萬次查詢完成去作業務處理就超時了,而後消息進行重試,又被其餘實例消費,繼續查詢5萬次,查詢了下該表索引,發現只有orderId 這個字段有索引,全部查詢其餘字段的時候還要掃表,致使cpu升高,讀寫變慢,消息積壓,臨時方案,修改了下mq超時時間,放次消息消費過去,而後開始着手,從新建索引,而後就有了以下的分析。mysql

這張表除了這個查詢語句之外,還有查詢條件爲(orderIdserviceId),(orderIdskuUuid)的語句,那麼如何建索引才更合理呢, 初始版本一個聯合索引(orderIdserviceId,skuUuid),可是在(orderIdskuUuid)時skuUuid沒法使用索引,依然會有以前的問題,第二個版本建2個聯合索引(orderIdserviceId, skuUuid),(orderId, skuUuid)這樣能夠都使用到索引了。那麼問題來了,爲何索引要有最左前綴,爲何中間少了一個字段後面的就不能使用索引了呢? 好比原表中的數據是這樣的:sql

創建了(orderIdserviceId,skuUuid)複合索引以後,索引文件數據應該是這樣的:post

從全表來看orderId是有序的,而serviceId和skuUuid是相對有序的,因此若是沒有orderId,直接訪問serviceId或skuUuid,那確定是無序的,因此也就用不到索引了,因此聯合索引就相似於闖關同樣,要一關一關的來,斷開則後面的都沒法使用到索引。ui

留下幾個感受比較好的連接已備後面複習,你們也能夠看看。.net

www.cnblogs.com/rjzheng/p/9… 煙哥牛逼!code

juejin.im/post/5d23ef…cdn

blog.csdn.net/u014029277/…htm

blog.csdn.net/zly9923218/…blog

相關文章
相關標籤/搜索