一。sql执行顺序
1.from:以最右表为基表,从右到左进行交叉链接生成虚表V1,所以小表应放最后边(循环次数少);
2.on:将虚表v1使用on后条件进行筛选得到虚表v2
3.join:在虚表v2的基础之上添加保留表(通过left right full判断)中被删除的数据,添加数据中对应非保留表字段值为null,最后得到虚表v3;如果有多张表则重复上诉步骤。
①嵌套循环连接(Nested Loop Join)
遍历驱动表每一条数据之后根据链接列内层循环查询被驱动表数据,如果被驱动表链接列有索引则可以进行index seek 否则进行 index scan。该种链接方式适用于驱动表筛选后数据较小且被驱动表链接列有索引,否则explan解释器更倾向于使用Hash Join。
注意:
Ⅰ。select是需指定列尽量避免书签查找(回表),如果回表数量较大可能会造成index scan。
Ⅱ。如果where条件后有较多比较字符(< > =),explan估计的行数和实际的行数存在巨大的偏差,从而使应该用 index scan的sql最后选择了书签查找,这种情况对性能的影响将会比index scan更加巨大
②合并连接(Merge Join)
如果两张表都按照顺序排列且链接条件中包含等号,则explan解释器会选择合并链接。比如sql中包含Order By,Group By。
③哈希匹配(Hash Join)
简单来说就是将两张1链接表的链接条件计算hash值,放入到对应的hash桶中进行匹配。
4.where:将虚表v3使用where后条件进行筛选得到虚表v4;
5.group by:将虚表v4根据指定字段分组得到虚表v5,
6.此时可以使用别名,同时开始执行聚合函数:
①AVG:返回平均值
②COUNT:返回行数
③FIRST:返回第一个记录的值
④LAST:返回最后一个记录的值
⑤MAX: 返回最大值
⑥MIN:返回最小值
⑦SUM: 返回总和
7.with cube 和 with rollup:生成虚拟表v6
8.having:在v6的基础上过滤生成v7,该条件必须与group by一起使用;
9.select:选出对应的列,并执行select字句表达式生成虚表v8;
10.union: 联合查询
10.distinct:去除重复的行生成虚表v9;
11.order by:将虚表v9按条件(从左到右)排序生成游标vc10(非常消耗资源)
12.limit/offset:从vc10选择指定返回行,生成虚表v11返回调用者。
二。基本原则
1.联合索引:最左前缀匹配即是where条件必须有联合索引的第一个字段。与顺序无关
2.对于not exists查询,内表存在空值对查询结果没有影响;对于not in查询,内表存在空值将导致最终的查询结果为空。in 和 exists性能差距不大,区别在于:in相当于是将子查询数据使用or进行链接判断,而exists相当于是一个loop循环进行判断。
3.非关联子查询中子sql无需依赖母sql数据,最先执行。而关联子查询子sql需要依赖母sql数据,嵌套在母查询的执行顺序中。所以尽量使用非关联子查询。