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...