mysql-联接查询-增加索引

联接查询-增加索引(对于内连接)

更多情况:联接查询-驱动表

1.对应的表

CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));

2.连接查询(不带索引)

EXPLAIN select *   from   dept_emp as d inner join salaries  as s  on s.to_date=d.to_date;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                              |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
|  1 | SIMPLE      | d     | NULL       | ALL  | NULL          | NULL | NULL    | NULL |  110 |   100.00 | NULL                                               |
|  1 | SIMPLE      | s     | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 2814 |    10.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+

显然对于没有加索引的两张表,两张表全部进行的全表查询,查询次数1102814,很慢*

2.连接查询(数据少的表少上索引)

CREATE index to_date_ids on dept_emp(to_date)
EXPLAIN select *   from   dept_emp as d inner join salaries  as s  on s.to_date=d.to_date;
+----+-------------+-------+------------+------+---------------+-------------+---------+----------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key         | key_len | ref            | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------------+---------+----------------+------+----------+-------+
|  1 | SIMPLE      | s     | NULL       | ALL  | NULL          | NULL        | NULL    | NULL           | 2814 |   100.00 | NULL  |
|  1 | SIMPLE      | d     | NULL       | ref  | to_date_ids   | to_date_ids | 3       | test.s.to_date |   36 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+-------------+---------+----------------+------+----------+-------+

表dept_emp加上了索引,查询次数减少为362814*

3.连接查询(数据多的表加上索引)

drop index to_date_ids  on dept_emp
CREATE index to_date_ids on salaries(to_date)
EXPLAIN select *   from   dept_emp as d inner join salaries  as s  on s.to_date=d.to_date;
+----+-------------+-------+------------+------+---------------+-------------+---------+----------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key         | key_len | ref            | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------------+---------+----------------+------+----------+-------+
|  1 | SIMPLE      | d     | NULL       | ALL  | NULL          | NULL        | NULL    | NULL           |  110 |   100.00 | NULL  |
|  1 | SIMPLE      | s     | NULL       | ref  | to_date_ids   | to_date_ids | 3       | test.d.to_date |   33 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+-------------+---------+----------------+------+----------+-------+
CREATE index to_date_ids on dept_emp(to_date)

对于数据多的表salaries使用到了索引,只查询了33条数据,而表 dept_emp进行了全表查询,查询次数减少为110*33,极大的优化了查询次数

4.连接查询(都加上索引)

CREATE index to_date_ids on dept_emp(to_date)
EXPLAIN select *   from   dept_emp as d inner join salaries  as s  on s.to_date=d.to_date;
+----+-------------+-------+------------+------+---------------+-------------+---------+----------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key         | key_len | ref            | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------------+---------+----------------+------+----------+-------+
|  1 | SIMPLE      | d     | NULL       | ALL  | NULL          | NULL        | NULL    | NULL           |  110 |   100.00 | NULL  |
|  1 | SIMPLE      | s     | NULL       | ref  | to_date_ids   | to_date_ids | 3       | test.d.to_date |   33 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+-------------+---------+----------------+------+----------+-------+

结果同上

结论:

1.当联接查询两张表时,某一张表A存在索引,那么另一张表B会进行全表查询。在表B中查出一条记录,再去表A中查询是根据索引查询是否满足联接条件,满足则联接成功。
2.对于两张表都加上索引,对于上一种情况(数据多的表加索引)并不会有优化
所以应该选择记录多的表加上索引,避免数据多的表进行全表查询
就是将记录多的表作为被驱动表(对于内连接,驱动表选择方式联接查询-驱动表),对其加上索引。
ps:选择加索引时,数据量的多少,是不重复的数据量

你可能感兴趣的:(Mysql)