首先我们先创建一个数据库, 数据库中分别写三张表来存储数据;
course: 课程表
teacher: 教师表
teacherCarid: 教师证表
现在我把这三张表连起来查, 查询条件: 查询课程编号为 2 或教师证编号为 3 点老师信息;
通过这个例子, 我们就可以把 explain 里面的参数一个一个的讲讲:
首先这个条件的主干是查询老师信息;
sql 语句: select t.* From teacher t INNER JOIN course c INNER JOIN teachercarid te WHERE t.tid = c.cid AND t.tcid = te.tcid AND (c.cid = 2 or te.tcid = 3);
执行结果:
SQL 语句很简单, 我们不关心这个, 我们关心的是在它前面加 explain:
explainselect t.* From teacher t INNER JOIN course c INNER JOIN teachercarid te WHERE t.tid = c.cid AND t.tcid = te.tcid AND (c.cid = 2 or te.tcid = 3);
执行看结果:
先看 id:
id 此时此刻都是 1, 它们都对应我们的表 te 是我们的教师证表 t 就是教室表 c 是课程表
由此可见, 我们编写的 SQL 语句它底层是先执行教师证表的, 然后执行教室表, 最后再执行课程表;
那这是为什么呢?
我们来分析一下数据:
course: 课程表 有三条数据
teacher: 教师表 有三条数据
teacherCarid: 教师证表 有四条数据
难道是数据越少就先执行谁? 我们不妨来做个试验看看, 我再加几条数据:
现在我们的数据变更为:
course: 课程表 有三条数据
teacher: 教师表 有四条数据
teacherCarid: 教师证表 有六条数据;
我们再看它的执行计划:
通过试验我们发现, 确实谁少就先执行谁, 但是我我们却发现, 表的执行顺序是因数量的个数改变而改变, 那它的原因是什么呢? 为什么表的执行顺序会跟随个数而改变呢?
笛卡尔积
我们现在假设 a b 两张表, a 里面有三条数据, b 里面有六条数据, 最后他俩相乘 = 18;
我们假设现在有 a b c 三张表, 第一张表 a 是三条数据 第二张表是 3 条数据第三表的数据是 4, 那它们的笛卡尔积 2*3 = 6 6 再 * 4 = 24;
这个时候我们换一下位置 a 是四条数据 b 是三条数据 c 是两条数据, 我们再来算一下它们的笛卡尔积: 3*4 = 12 *2 = 24;
我们发现两者结果都没有变, 但是中间结果变了, 第一次计算笛卡尔积时 第一次计算 2*3 =6, 第二次计算笛卡尔积时 3*4 = 12, 因为 6 比 12 小索所以它就先执行;
为什么在图上, c 先执行的原因是 c * t (3*4 = 12)te 是 6, 所以比较大, 就向后放;
结论: 数据小的表, 会优先查询;
ID 值越大越优先执行
id 值相同, 就从上往下依次执行, 如果不相同, 那就从下往上执行, 因为 id 值越大, 它就越往下排列;
Select_type
PRIMARY: 包含查询 SQL 中的子查询(最外层)
SUBQUERY: 包含子查询 SQL 中的子查询(非最外层)
Simple: 简单查询 (一个 SQL 语句里面不包含子查询, union) 都是简单查询
derived: 衍生查询 触发子衍生查询只有两种:
1. 在 from 子查询中, 只有一张表
2. 在 from 子查询中如果有两张表, 比如 tablie1 union table2, 则 table1 就是衍生查询;
来源: http://www.linuxidc.com/Linux/2019-03/157263.htm