mysql 多表索引 mysql 兩表索引優化

2021-10-17 13:31:57 字數 3787 閱讀 8790

建表語句

create table if not exists `class`(

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

`card` int(10) unsigned not null,

primary key(`id`)

create table if not exists `book`(

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

`card` int(10) unsigned not null,

primary key(`bookid`)

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 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)));

使用explain對sql進行檢查

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

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra |

| 1 | ****** | class | null | all | null | null | null | null | 24 | 100.00 | null |

| 1 | ****** | book | null | all | null | null | null | null | 1 | 100.00 | using where; using join buffer (block nested loop) |

2 rows in set, 1 warning (0.00 sec)

可以看到type都為all(執行全表查詢)

使用了join緩衝區(其使用的演算法為block nested-loop(bnl))

新增索引

對book表的card屬性新增索引

alter table `book` add index y(`card`);

再次用explain檢視之前的sql

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

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra |

| 1 | ****** | class | null | all | null | null | null | null | 24 | 100.00 | null |

| 1 | ****** | book | null | ref | y | y | 4 | test.class.card | 1 | 100.00 | using index |

2 rows in set, 1 warning (0.00 sec)

可以看到book表的type優化為了type, 且extra變為了using index, 不會再使用緩衝區了。

對class表的card屬性新增索引

alter table `class` add index y(`card`);

再次用explain檢視之前的sql

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

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra |

| 1 | ****** | class | null | index | null | y | 4 | null | 24 | 100.00 | using index |

| 1 | ****** | book | null | ref | y | y | 4 | test.class.card | 1 | 100.00 | using index |

2 rows in set, 1 warning (0.00 sec)

可以看到type變為了index, ref 而 extra 都變為了using index

可以得出的結論

左連線時, 對右表建索引進行優化更重要(左表都保留, 必然全表掃瞄)

右連線時, 對左表建索引進行優化更重要(右表都保留, 必然全表掃瞄)

mysql多表連線索引問題

要想明白多表連線過程中索引是否起作用,哪個表的索引起作用。首先先了解在join連線時哪個表是驅動表,哪個表是被驅動表 1.當使用left join時,左表是驅動表,右表是被驅動表,2.當使用right join時,右表時驅動表,左表是被驅動表,3.當使用join時,mysql會選擇資料量比較小的表作...

mysql多表 MySQL 多表查詢

多表查詢 select listname from tablename1,tablename2 笛卡爾積 多表查詢中,如果沒有連線條件,則會產生笛卡爾積 數學中的定義 假設集合a 集合b 則兩個集合的笛卡爾積為 實際執行環境下,應避免使用笛卡爾積 解決方案 在where加入有效的連線條件 等值連線 ...

mysql之多表建立索引分析

一.2張表分析 select form users left join dept on users.deptid dept.id 以左邊為驅動,左邊表的資料自然全有了,所以要再dept表建立id索引,我這舉的是個特例了,因為部門表id是主鍵,自動建立索引了。二.3張表分析 select form u...