建表语句

CREATE TABLE IF NOT EXISTS `phone`(
`phoneid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`card` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY(`phoneid`)
)ENGINE = INNODB; INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO phone(card) VALUES(FLOOR(1 + (RAND() * 20)));

使用explain解读SQL

mysql> explain select * from class LEFT JOIN book on class.card=book.card LEFT JOIN phone on book.card = phone.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 |
| 1 | SIMPLE | phone | NULL | ALL | NULL | NULL | NULL | NULL | 20 | 100.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+-------+---------------+------+---------+-----------------+------+----------+----------------------------------------------------+
3 rows in set, 1 warning (0.00 sec)
  • 可以看到phone表的type为all, Extra中显示使用了连接缓冲区区。

创建phone表的card索引

alter table `phone` add index Z(`card`);
  • 再用explain查看sql语句

    mysql> explain select * from class LEFT JOIN book on class.card=book.card LEFT JOIN phone on book.card = phone.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 |
    | 1 | SIMPLE | phone | NULL | ref | Z | Z | 4 | test.book.card | 1 | 100.00 | Using index |
    +----+-------------+-------+------------+-------+---------------+------+---------+-----------------+------+----------+-------------+
    • 注意rows: 扫描的行数
  • 其实可以做更好的优化:

    mysql> explain select * from phone LEFT JOIN book on phone.card=book.card LEFT JOIN class on book.card = class.card;
    +----+-------------+-------+------------+-------+---------------+------+---------+-----------------+------+----------+-------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    +----+-------------+-------+------------+-------+---------------+------+---------+-----------------+------+----------+-------------+
    | 1 | SIMPLE | phone | NULL | index | NULL | Z | 4 | NULL | 20 | 100.00 | Using index |
    | 1 | SIMPLE | book | NULL | ref | Y | Y | 4 | test.phone.card | 1 | 100.00 | Using index |
    | 1 | SIMPLE | class | NULL | ref | Y | Y | 4 | test.book.card | 1 | 100.00 | Using index |
    +----+-------------+-------+------------+-------+---------------+------+---------+-----------------+------+----------+-------------+
    3 rows in set, 1 warning (0.00 sec)
    • 思想: 用小表驱动大表, 能更好地减少行扫描次数。
  • 结论:

    • 索引最好设置在需要经常查询的字段中
    • 尽可能减少Join语句中的NestedLoop的循环总数
    • 永远用小结果集驱动大的结果集

mysql 三表索引优化的更多相关文章

  1. MySQL的索引优化分析(二)

    一.索引优化 1,单表索引优化 建表 CREATE TABLE IF NOT EXISTS article( id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO ...

  2. 知识点:Mysql 数据库索引优化实战(4)

    知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 一:插入订单 业务逻辑:插 ...

  3. mysql使用索引优化查询效率

    索引的概念 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度.在没 ...

  4. mysql数据库索引优化与实践(一)

    前言 mysql数据库是现在应用最广泛的数据库系统.与数据库打交道是每个Java程序员日常工作之一,索引优化是必备的技能之一. 为什么要了解索引 真实案例 案例一:大学有段时间学习爬虫,爬取了知乎30 ...

  5. 【mysql】索引优化记录

    基础知识 Innodb存储引擎 支持行锁 支持事务: Myisam存储引擎 只支持表锁: 不支持事务: 常见索引列表 独立的列 前缀索引(索引选择性) 多列索引(并不是多个单列索引,索引顺序很重要) ...

  6. MySQL高级-索引优化

    索引失效 1. 2.最佳左前缀法则 4. 8. 使用覆盖索引解决这个问题. 二.索引优化 1.ORDER BY 子句,尽量使用Index方式排序,避免使用FileSort方式排序 MySQL支持两种方 ...

  7. MySQL的索引优化,查询优化

    MySQL逻辑架构 如果能在头脑中构建一幅MySQL各组件之间如何协同工作的架构图,有助于深入理解MySQL服务器.下图展示了MySQL的逻辑架构图. MySQL逻辑架构,来自:高性能MySQL My ...

  8. mysql数据库索引优化

    参考 :http://www.cnblogs.com/yangmei123/archive/2016/04/10/5375723.html MySQL数据库的优化:    数据库优化的目的:     ...

  9. MySQL的索引优化分析(一)

    一.SQL分析 性能下降.SQL慢.执行时间长.等待时间长 查询语句写的差 索引失效关联查询太多join(设计缺陷) 单值索引:在user表中给name属性创建索引,create index idx_ ...

随机推荐

  1. 转入软工后第一节java课的作业

    这个作业,鸽了好久.本来大家都在中秋前发了,我摸摸索索加上各种缓慢的学习,终于是将他做完了. 做完之后,java最基本的输入输出功能都基本学习到了.下面附上代码: import java.util.* ...

  2. java web 学生信息录入

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  3. 高级T-SQL进阶系列 (一)【上篇】:使用 CROSS JOIN 介绍高级T-SQL

    [译注:此文为翻译,由于本人水平所限,疏漏在所难免,欢迎探讨指正] 原文连接:传送门 这是一个新进阶系列的第一篇文章,我们将浏览Transact-SQL(T-SQL)的更多高级特性.这个进阶系列将会包 ...

  4. C++98常用特性介绍——mutable关键字

    讲mutable前,先讲一下const函数,讲const函数前,先讲一下函数前后加const的区别 一.C++函数前后加const的区别 1)函数前加const:普通函数或非静态成员函数前均可加con ...

  5. PB specified database is invalid

    拷贝资料库到其他机器,可以重新配置ODBC ,如果还是报错,建议删除log .

  6. 「JSOI2014」学生选课

    「JSOI2014」学生选课 传送门 看到这题首先可以二分. 考虑对于当前的 \(mid\) 如何 \(\text{check}\) 我们用 \(f_{i,j}\) 来表示 \(i\) 对 \(j\) ...

  7. Go语言学习笔记(三)

    一.浮点数 1.概述 浮点类型用于存储带有小数点的数字 一个整数数值可以赋值给浮点类型但是一个整型变量不可以赋值给浮点类型 浮点数进行运算的结果是浮点数 Go语言中浮点类型有两个 float32 fl ...

  8. 十二 Spring的AOP开发入门,整合Junit单元测试(AspectJ的XML方式)

    创建web项目,引入jar包 引入Spring配置文件

  9. .net core 2.1控制台使用Quartz.net实现定时任务执行

    权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/qq_33435149/article/de ...

  10. [转]:Ubuntu 下Apache安装和配置

    [转]:Ubuntu 下Apache安装和配置_服务器应用_Linux公社-Linux系统门户网站  https://www.linuxidc.com/Linux/2013-06/85827.htm ...