目录
- 一、建表语句
- 二、索引两表左关联优化分析(以class表为左表,book表为右表演示)
- 三、索引两表右关联优化分析(以class表为左表,book表为右表演示)
- 四、索引两表优化总论
一、建表语句
1、书籍的类别表建表语句
CREATE TABLE IF NOT EXISTS `class` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '分类id' ,
`card` INT(10) UNSIGNED NOT NULL COMMENT '类别',
PRIMARY KEY (`id`)
)COMMENT='书籍的类别表';
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)));
2、书籍表的建表语句
CREATE TABLE IF NOT EXISTS `book` (
`bookid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '书籍id',
`card` INT(10) UNSIGNED NOT NULL COMMENT '类别',
PRIMARY KEY (`bookid`)
)COMMENT='书籍表';
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)));
二、索引两表左关联优化分析(以class表为左表,book表为右表演示)
1、执行2张表的索引查询sql如下:
SHOW INDEX FROM book;SHOW INDEX FROM class;
- 结论:只有主键索引
2、直接执行explain查看情况
EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card;
- 结论:type 有All,需要进行优化。因为type的常用访问类型结果值从最好到最坏依次是:system>const>eq_ref>ref>range>index>ALL,得保证查询至少达到range级别,最好能达到ref。
3、第一次优化(左表即class表中建立索引)
(1)、在左表(即class表)中建立索引,并查看所建立的索引。
ALTER TABLE class ADD INDEX index_car (card);SHOW INDEX FROM class ;
(2)、执行EXPLAIN
EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card;
- 结论:左表(即class表)的type变成了index,比type为all的级别高一级。因为type的常用访问类型结果值从最好到最坏依次是:system>const>eq_ref>ref>range>index>ALL,得保证查询至少达到range级别,最好能达到ref。
4、第二次优化(右表即book表中建立索引)
(1)、先删除第一次优化创建的旧索引,并查看索引情况。
DROP INDEX index_car ON class ;SHOW INDEX FROM class ;
- 结论:只有主键索引
(2)、在右表(即book表)中建立索引,并查看所建立的索引。
ALTER TABLE book ADD INDEX index_car (card);SHOW INDEX FROM book;
(3)、执行EXPLAIN
EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card;
- 结论:可以看到第二行的 type 变为了ref,rows也变成了优化比较明显。这是由左连接特性决定的。LEFT JOIN 条件用于确定如何从右表搜索行,左边一定都有,所以左连接时右表是我们的关键点,一定需要建立索引。
三、索引两表右关联优化分析(以class表为左表,book表为右表演示)
1、执行2张表的索引查询sql如下:
SHOW INDEX FROM book;SHOW INDEX FROM class;
- 结论:只有主键索引
2、直接执行explain查看情况
EXPLAIN SELECT * FROM class RIGHT JOIN book ON class.card = book.card;
- 结论:type 有All,需要进行优化。因为type的常用访问类型结果值从最好到最坏依次是:system>const>eq_ref>ref>range>index>ALL,得保证查询至少达到range级别,最好能达到ref。
3、第一次优化(右表即book表中建立索引)
(1)、在右表(即book表)中建立索引,并查看所建立的索引。
ALTER TABLE book ADD INDEX index_car (card);SHOW INDEX FROM book;
(2)、执行EXPLAIN
EXPLAIN SELECT * FROM class RIGHT JOIN book ON class.card = book.card;
- 结论:右表(即book表)的type变成了index,比type为all的级别高一级。因为type的常用访问类型结果值从最好到最坏依次是:system>const>eq_ref>ref>range>index>ALL,得保证查询至少达到range级别,最好能达到ref。
4、第二次优化(左表即class表中建立索引)
(1)、先删除第一次优化创建的旧索引,并查看索引情况。
DROP INDEX index_car ON book;SHOW INDEX FROM book;
- 结论:只有主键索引
(2)、在左表(即class表)中建立索引,并查看所建立的索引。
ALTER TABLE class ADD INDEX index_car (card);SHOW INDEX FROM class;
(3)、执行EXPLAIN
EXPLAIN SELECT * FROM class RIGHT JOIN book ON class.card = book.card;
- 结论:可以看到第二行的 type 变为了ref,rows也变成了优化比较明显。这是由右连接特性决定的。RIGHT JOIN 条件用于确定如何从左表搜索行,右边一定都有,所以右连接时左表是我们的关键点,一定需要建立索引。
四、索引两表优化总论
- 左连接时右表建立索引
- 右连接时左表建立索引