建表语句

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 | SIMPLE | class | NULL | ALL | NULL | NULL | NULL | NULL | 24 | 100.00 | NULL |
| 1 | SIMPLE | 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 | SIMPLE | class | NULL | ALL | NULL | NULL | NULL | NULL | 24 | 100.00 | NULL |
    | 1 | SIMPLE | 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 | SIMPLE | class | NULL | index | NULL | Y | 4 | NULL | 24 | 100.00 | Using index |
    | 1 | SIMPLE | 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 两表索引优化的更多相关文章

  1. mysql 单表索引优化

    建表语句 CREATE TABLE IF NOT EXISTS `article` ( `id` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMEN ...

  2. MySql在建立索引优化时需要注意的问题

    MySql在建立索引优化时需要注意的问题 设计好MySql的索引可以让你的数据库飞起来,大大的提高数据库效率.设计MySql索引的时候有一下几点注意: 1,创建索引 对于查询占主要的应用来说,索引显得 ...

  3. MySQL中的索引优化

    MySQL中的SQL的常见优化策略 MySQL中的索引优化 MySQL中的索引简介 过多的使用索引将会造成滥用.因此索引也会有它的缺点.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行 ...

  4. mysql 高级和 索引优化,目的:查的好,查的快,性能好

    1-事物隔离级别: 更新丢失, 并发情况下,对同一字段进行更新,就会出现更新丢失,采用乐观锁,比较版本号或时间戳可解决 读未提交 解决了更新丢失但是会引起脏读, 二个session.sessionA中 ...

  5. MySQL 多列索引优化小记

    MySQL 5.6.30 问题背景 由于爬虫抓取的数据不断增多,这两天在不断对数据库以及查询语句进行优化,其中一个表结构如下: CREATE TABLE `newspaper_article` ( ` ...

  6. Mysql学习总结(35)——Mysql两千万数据优化及迁移

    最近有一张2000W条记录的数据表需要优化和迁移.2000W数据对于MySQL来说很尴尬,因为合理的创建索引速度还是挺快的,再怎么优化速度也得不到多大提升.不过这些数据有大量的冗余字段和错误信息,极不 ...

  7. MySQL系列(六)--索引优化

    在进行数据库查询的时候,索引是非常重要的,当然前提是达到一定的数据量.索引就像字典一样,通过偏旁部首来快速定位,而不是一页页 的慢慢找. 索引依赖存储引擎层实现,所以支持的索引类型和存储引擎相关,同一 ...

  8. 【MySQL 高级】索引优化分析

    MySQL高级 索引优化分析 SQL 的效率问题 出现性能下降,SQL 执行慢,执行时间长,等待时间长等情况,可能的原因有: 查询语句写的不好 索引失效 单值索引:在 user 表中给 name 属性 ...

  9. MySQL如何利用索引优化ORDER BY排序语句

    MySQL索引通常是被用于提高WHERE条件的数据行匹配或者执行联结操作时匹配其它表的数据行的搜索速度. MySQL也能利用索引来快速地执行ORDER BY和GROUP BY语句的排序和分组操作. 通 ...

随机推荐

  1. 无线客户端掉线(Disassociate and DeleteReason)

  2. 前端开发中的 MVC、MVP、MVVM 模式

    MVC,MVP和MVVM都是常见的软件架构设计模式(Architectural Pattern),它通过分离关注点来改进代码的组织方式.不同于设计模式(Design Pattern),只是为了解决一类 ...

  3. java finalize学习

    1 finalize()调用的时机 与C++的析构函数(对象在清除之前析构函数会被调用)不同,在Java中,由于GC的自动回收机制,因而并不能保证finalize方法会被及时地执行(垃圾对象的回收时机 ...

  4. 代理模式之静态代理,JDK动态代理和cglib动态代理

    代理模式,顾名思义,就是通过代理去完成某些功能.比如,你需要购买火车票,不想跑那么远到火车站售票窗口买,可以去附近的火车票代售点买,或者到携程等第三方网站买.这个时候,我们就把火车站叫做目标对象或者委 ...

  5. 操作系统OS,Python - 协程(Coroutine)

    留坑 参考: https://en.wikipedia.org/wiki/Coroutine https://zh.wikipedia.org/wiki/%E5%8D%8F%E7%A8%8B http ...

  6. python 的参数总结

    一.形参和实参 函数参数的作用是传递数据给函数使用 在使用的过程中,参数有两种形式:形式参数和实际参数 形参: 定义函数的参数 实参: 调用函数时的参数 根据实际参数类型不同,将实际参数传递给形参的方 ...

  7. 玩转NB-IOT模块之sim7000c

    https://blog.csdn.net/liwei16611/article/details/82698926 http://bbs.21ic.com/icview-2104630-1-1.htm ...

  8. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 显示代码

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  9. STM32的程序升级

    IAP基础参考http://www.eeworld.com.cn/mcu/2018/ic-news112042038.html https://blog.csdn.net/tq384998430/ar ...

  10. LeetCode 101.对称二叉树 - JavaScript

    题目描述:给定一个二叉树,检查它是否是镜像对称的. 题目分析 下面这种二叉树就是镜像对称的,符合题目要求: 1 / \ 2 2 / \ / \ 3 4 4 3 解法 1:递归检查 根据题目" ...