mysql索引优化2

mysql 索引分析案例2_两表优化

建表

mysql> create table class(
    -> id int(10) not null auto_increment,
    -> card int(10) not null,
    -> primary key(id)
    -> );
Query OK, 0 rows affected (0.21 sec)

mysql> create table book(
    -> bookid int(10) not null auto_increment,
    -> card int(10) not null,
    -> primary key(bookid)
    -> );
Query OK, 0 rows affected (0.18 sec)

//插入数据
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(1+(rand()*20));
insert into class(card) values(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)))


//查看数据
mysql> select * from book;
+--------+------+
| bookid | card |
+--------+------+
|      1 |    7 |
|      2 |    7 |
|      3 |   12 |
|      4 |   19 |
|      5 |    1 |
|      6 |    5 |
|      7 |    3 |
|      8 |   20 |
|      9 |   11 |
|     10 |   16 |
|     11 |    4 |
|     12 |   12 |
|     13 |   10 |
|     14 |   10 |
|     15 |    1 |
|     16 |   14 |
|     17 |    6 |
|     18 |    6 |
|     19 |   14 |
|     20 |   11 |
+--------+------+
20 rows in set (0.00 sec)

mysql> select * from class;
+----+------+
| id | card |
+----+------+
|  1 |   15 |
|  2 |   10 |
|  3 |    3 |
|  4 |    2 |
|  5 |    3 |
|  6 |    5 |
|  7 |   15 |
|  8 |   20 |
|  9 |   15 |
| 10 |   14 |
| 11 |    4 |
| 12 |   16 |
| 13 |    7 |
| 14 |    4 |
| 15 |    2 |
| 16 |   14 |
| 17 |    3 |
| 18 |   12 |
| 19 |   11 |
| 20 |   16 |
+----+------+
20 rows in set (0.00 sec)

案例1分析

两张表数据没有任何实际意义,案例也没有任何意义,只是为了出问题,解决问题关于案例并不由纠结太多- - #
1.使用left join 查询两张表

mysql> explain select * from class left join book on class.card=book.card;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                              |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
|  1 | SIMPLE      | class | ALL  | NULL          | NULL | NULL    | NULL |   20 | NULL                                               |
|  1 | SIMPLE      | book  | ALL  | NULL          | NULL | NULL    | NULL |   20 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
2 rows in set (0.00 sec)

我们发现出现了全表扫描,先来解决这个问题,但是涉及到了两张表我们应该在那张表来建立索引,大胆假设,小心求证我们一一来尝试一下就知道了首先我们选择book的card来建立索引

mysql> create index idx_book_c on book(card);
Query OK, 0 rows affected (0.13 sec)
Records: 0  Duplicates: 0  Warnings: 0

我们在尝试一下 使用左连接查询在右表建立索引

mysql> explain select * from class left join book on class.card=book.card;
+----+-------------+-------+------+---------------+------------+---------+-----------------+------+-------------+
| id | select_type | table | type | possible_keys | key        | key_len | ref             | rows | Extra       |
+----+-------------+-------+------+---------------+------------+---------+-----------------+------+-------------+
|  1 | SIMPLE      | class | ALL  | NULL          | NULL       | NULL    | NULL            |   20 | NULL        |
|  1 | SIMPLE      | book  | ref  | idx_book_c    | idx_book_c | 4       | test.class.card |    1 | Using index |
+----+-------------+-------+------+---------------+------------+---------+-----------------+------+-------------+
2 rows in set (0.00 sec)

我们发现book全表扫描已经变成了ref 也使用到了索引,且查询行数变成了1 已经有明显的改变,我们在尝试一下在左表建立索引对比一下

//删除索引
drop index idx_book_c on book;

//在左表建立索引
create index idx_class_c on class(card);

//再次尝试
mysql> explain select * from class left join book on class.card=book.card;
+----+-------------+-------+-------+---------------+-------------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type  | possible_keys | key         | key_len | ref  | rows | Extra                                              |
+----+-------------+-------+-------+---------------+-------------+---------+------+------+----------------------------------------------------+
|  1 | SIMPLE      | class | index | NULL          | idx_class_c | 4       | NULL |   20 | Using index                                        |
|  1 | SIMPLE      | book  | ALL   | NULL          | NULL        | NULL    | NULL |   20 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+-------+---------------+-------------+---------+------+------+----------------------------------------------------+
2 rows in set (0.00 sec)

我们发现type 为index 且 row20 并没有得到优化

案例1 结论

由于是左连接,left join 条件用于确定如何草右表搜索行,左边一定都有,所以右边使我们的关键点,一定需要建立索引.
索引我们还是删除之前的索引

mysql> drop index idx_class_c on class;
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0

//还是在右表建立索引吧
mysql> create index idx_book_c on book(card);
Query OK, 0 rows affected (0.20 sec)
Records: 0  Duplicates: 0  Warnings: 0

//发现回到了刚开始的样子	- - !
mysql> explain select * from class left join book on class.card=book.card;
+----+-------------+-------+------+---------------+------------+---------+-----------------+------+-------------+
| id | select_type | table | type | possible_keys | key        | key_len | ref             | rows | Extra       |
+----+-------------+-------+------+---------------+------------+---------+-----------------+------+-------------+
|  1 | SIMPLE      | class | ALL  | NULL          | NULL       | NULL    | NULL            |   20 | NULL        |
|  1 | SIMPLE      | book  | ref  | idx_book_c    | idx_book_c | 4       | test.class.card |    1 | Using index |
+----+-------------+-------+------+---------------+------------+---------+-----------------+------+-------------+
2 rows in set (0.00 sec)

##案例2
不想多说了同理 ,如果采用右连接 当然是左表建立索引比较好

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL索引优化是提高查询性能的关键。下面是一些优化MySQL索引的方法: 1. 选择合适的索引 索引并非越多越好,需要根据实际情况选择合适的索引。通常来说,可以根据以下几个原则来选择索引: - 对经常查询的列进行索引 - 对频繁用于WHERE、JOIN、ORDER BY和GROUP BY子句的列进行索引 - 对选择性高的列进行索引(即不同值越多的列) 2. 删除不必要的索引 过多的索引会占用过多的磁盘空间并降低写操作的性能,因此需要删除不必要的索引。可以使用如下语句查询所有的索引,并根据实际情况删除不必要的索引: ``` SHOW INDEX FROM table_name; ``` 3. 避免全表扫描 全表扫描是指MySQL查询时没有使用索引,而是扫描整个表的数据。全表扫描会导致查询效率低下,因此需要避免全表扫描。可以通过优化查询语句,例如添加索引、改变表结构等方式来避免全表扫描。 4. 使用覆盖索引 覆盖索引是指查询语句只需要使用索引中的列就可以返回查询结果,而不需要再去查询表中的数据。覆盖索引可以减少查询的IO操作,提高查询效率。 5. 定期维护索引 索引需要定期维护,包括优化查询语句、删除不必要的索引、重新构建索引等。可以使用MySQL自带的OPTIMIZE TABLE命令来优化表的索引和碎片,从而提高查询性能。 以上就是MySQL索引优化的一些方法,需要根据实际情况进行选择和优化。需要注意的是,不同的索引优化策略对于不同的数据库环境和数据结构可能会有所不同,需要根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值