MySQL 使用索引覆蓋優化業務查詢

2021-08-17 15:02:13 字數 1132 閱讀 9952

一、

在mysql表中,有一項無法忽略的部分,那就是索引——因為它直接或間接的決定了業務查詢的時間複雜度。乙個差的索引,會導致sql操作需要掃瞄全表,來查出符合條件的資料行,這當然是乙個悲劇。我們有必要,但也很容易去避免以下這種情況的發生,只要針對業務查詢建對應的索引就可以了。

但是,只需要建出對應的索引就可以了嗎?當然是不夠的,核心操作業務如果需要的字段很少,通過索引覆蓋,效能可以達到乙個質的飛躍。

二、在最近涉及的業務當中,有乙個比較簡單的點讚服務。模組維護人當時的建表是符合常理的:

create table `user_like` (

`item_id` bigint(20) not null,

`user_id` bigint(20) not null,

`insert_time` timestamp not null default current_timestamp,

key (`user_id, item_id`),

key (`user_id, insert_time`),)

engine=innodb default charset=utf8mb4

由於業務需求主要集中在兩項:

1. 檢視使用者是否對這個東西點過贊:select count(1) from user_like where user_id=xx and item_id=xx;

2. 查詢使用者的歷史點讚列表:select * from user_like where user_id=xx order by insert_time desc;

咋一看這兩個索引完美的契合了業務需求,但是實際上呢?

由於第2項業務在該產品中頻繁的觸發,即使有快取還是有大量的sql操作,雖然觸發索引key (user_id, insert_time)找到了對應的記錄,但是仍然需要讀取磁碟來查詢這條索引對應的item_id欄位,造成了乙個龐大的開銷。

解決辦法就是將其改為key (user_id, insert_time, item_id),即保留了user_id為某值且按insert_time排序的查詢需求,又在索引中保留有item_id。這樣第二項業務需求的查詢,就被索引「覆蓋了」。而單純只查詢索引的數值,基本上只需要通過記憶體中的快取,因此減少了大量打到磁碟的i/o。

mysql優化之覆蓋索引

1 當發起乙個被索引覆蓋的查詢時,在explain的extra列可以看到using index的資訊,此時就使用了覆蓋索引 mysql explain select store id,film id from inventory g 1.row id 1 select type table inve...

mysql 優化(4)索引覆蓋和最優索引

索引覆蓋 很重要的 乙個概念 就是在索引上查詢!如果查詢的列恰好是索引的一部分,那麼查詢只需要在索引檔案上進行 不需要回行到磁碟再找資料.這種查詢速度非常快,稱為 索引覆蓋 非聚促索引 索引檔案對應了資料要回行 浪費掉了時間 索引和資料區別 索引是高效組織起來的樹 節點 查詢樹葉 結構更優於資料 索...

MySQL覆蓋索引呼叫 MySQL 覆蓋索引

什麼是覆蓋索引 建立乙個索引,該索引包含查詢中用到的所有字段,稱為 覆蓋索引 使用覆蓋索引,mysql 只需要通過索引就可以查詢和返回查詢所需要的資料,而不必在使用索引處理資料之後再進行回表操作。覆蓋索引可以一次性完成查詢工作,有效減少io,提高查詢效率。使用示例 查詢語句 select col2,...