MySQL索引优化分析4—关联查询与子查询优化

MySQL索引优化分析4—关联查询与子查询优化

  • 1.关联查询优化
    • 1.1 案例
    • 1.2 建议
  • 2.子查询优化

之前介绍了单表查询中的索引优化,本节将介绍关联查询中的索引优化。

1.关联查询优化

案例将使用的数据表的创建如下:

# 1.创建图书类型表class
CREATE TABLE IF NOT EXISTS `class` (
	`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	`card` INT(10) UNSIGNED NOT NULL,
	PRIMARY KEY (`id`)
);
# 2.创建图书信息表book
CREATE TABLE IF NOT EXISTS `book` (
	`bookid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	`card` INT(10) UNSIGNED NOT NULL,
	PRIMARY KEY (`bookid`)
);

MySQL索引优化分析4—关联查询与子查询优化_第1张图片MySQL索引优化分析4—关联查询与子查询优化_第2张图片

1.1 案例

1)开始explain分析

EXPLAIN SELECT * FROM book  LEFT JOIN class ON class.card = book.card;

MySQL索引优化分析4—关联查询与子查询优化_第3张图片
结论:type 为 All,全表扫描。

2)为book的card字段添加索引优化,并删除class中id小于5的记录:

ALTER TABLE `book` ADD INDEX Y (`card`);
Delete from class where id<5;

3)第2次explain

# class为主表,book表为被驱动表:索引在book表上
EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card;

MySQL索引优化分析4—关联查询与子查询优化_第4张图片

可以看到第二行的 type 变为了 ref,rows 也变成了优化比较明显。

这是由左连接特性决定的。LEFT JOIN 条件用于确定如何从右表搜索行,而左边的行一定都有,所以右边是我们的关键点,一定需要建立索引。

4)可以对比索引表放在LEFT JOIN左边主表的位置:

MySQL索引优化分析4—关联查询与子查询优化_第5张图片

可以看出,虽使用了索引,但由于Left Join主表book的所有记录都需要查询,所以索引并没有发挥效用,rows依旧是20。

5)删除旧索引 + 新建class表新索引 + 使用inner join第3次explain

DROP INDEX Y ON book;
ALTER TABLE class ADD INDEX X (card);
EXPLAIN SELECT * FROM class Inner JOIN book ON class.card = book.card;

MySQL索引优化分析4—关联查询与子查询优化_第6张图片

inner join 时,mysql会将有索引的表选为被驱动表

1.2 建议

1)保证被驱动表的join字段已经被索引

2)left join 时,选择小表作为驱动表,大表作为被驱动表。

3)inner join 时,mysql会自己帮你把小结果集的表选为驱动表。

4)子查询尽量不要放在被驱动表,有可能使用不到索引。

5)能够直接多表关联的尽量直接关联,不用子查询。

2.子查询优化

1.尽量不要使用not in 或者 not exists

SELECT SQL_NO_CACHE  age,count(*)  
FROM emp a 
WHERE  id  NOT  IN (
		SELECT ceo 
		FROM dept b2 
		WHERE ceo IS NOT NULL
		)
Group By age 
Having count(*)<10000

MySQL索引优化分析4—关联查询与子查询优化_第7张图片
在这里插入图片描述
MySQL索引优化分析4—关联查询与子查询优化_第8张图片

2.用left outer join on xxx is null 替代 NOT IN

EXPLAIN SELECT SQL_NO_CACHE age,count(*) 
FROM  emp a LEFT OUTER JOIN dept b ON a.id =b.ceo
WHERE b.ceo IS   NULL
group by age 
having count(*)<10000

对比1的执行计划,有所提升:
MySQL索引优化分析4—关联查询与子查询优化_第9张图片
MySQL索引优化分析4—关联查询与子查询优化_第10张图片
MySQL索引优化分析4—关联查询与子查询优化_第11张图片

你可能感兴趣的:(数据库)