雙索引 mysql mysql 雙表索引優化

2021-10-19 23:35:40 字數 3903 閱讀 2233

1. 樣例資料:

version:mysql 8.0.19

create table if not exists `class`(

`id` int(10) unsigned not null auto_increment,

`card` int(10) unsigned not null,

primary key(`id`)

)engine=innodb auto_increment=1 default charset=utf8;

create table if not exists `book`(

`bookid` int(10) unsigned not null auto_increment,

`card` int(10) unsigned not null,

primary key(`bookid`)

)engine=innodb auto_increment=1 default charset=utf8;

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into class(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

insert into book(card) values(floor(1+(rand()*20)));

除了主鍵並沒有任何索引,所以

explain select * from book left join class on book.card = class.card;

初始索引狀態.png

type為all,需要優化。

1. 測試優化方案一

在左邊的book建立card索引,看看如何

create index idx_card on book(card);

show index from book;

book-索引.png

explain select * from book left join class on book.card = class.card;

此時檢測.png

book的索引all提公升為index,但是rows兩行,需要檢索的行數,仍然是21-24,沒有得到提公升。

2. 測試優化方案二

去除book表上的索引,新增在class的card列

drop index idx_card on book;

create index idx_card on class(card);

explain select * from book left join class on book.card = class.card;

class-card索引.png

當id都為1時,相等,則執行順序為由上而下,rows,需檢索行數分別為21和2,型別由all轉為ref,有了不小的提公升。

這是由於左連線的特性

左連線.png

a作為主表,a的記錄一定全部返回,能提公升的部分,由b部分決定,一定要對b表的檢索方式進行優化,故此b表需要建立索引。

永遠用小的結果集驅動大的結果集,小表放左邊,大表放右邊。

當無法保證b表join條件欄位被索引且記憶體資源充足的前提下,不要太吝嗇joinbuffer的設定。

雙表聯查mysql MySQL的雙表多表聯查

最近在做ec mall的二次開發,遇到這麼乙個需求,將掛件單獨顯示成乙個頁面。由於ec mall的掛件是用資料模組 模組類庫的方式進行的,就是使用類似smarty的形式。而單獨乙個頁面的話,資料讀取需要自己寫sql語句。現在的問題是,需要將商品中的汽車類中的推薦 最近在做ec mall的二次開發,遇...

雙指標 雙索引 演算法介紹 c

雙指標演算法在一些陣列題中很常用,它指的是一類使用兩個指標遍歷陣列求解問題的方法,這裡的指標是廣義上的,有可能是c c 中的指標,也有可能僅僅是兩個整數下標。雙指標演算法有兩種形式,一種被稱為對撞指標,兩個指標從兩端向中間靠攏 另一種是快慢指標,兩個指標向統一方向運動,滑動視窗方法就是一種常用的快慢...

MySQL優化索引之雙表優化

建表sql create table if not exists class id int 10 unsigned not null primary key auto increment,card int 10 unsigned not null create table if not exists...