1 sql mode参数解释
1 ONLY_FULL_GROUP_BY
对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,
那么将认为这个SQL是不合法的,因为列不在GROUP BY从句中。
2 STRICT_TRANS_TABLES
在该模式下,如果一个值不能插入到一个事务表中,
则中断当前的操作,对非事务表不做任何限制。
3 NO_ZERO_IN_DATE
在严格模式,不接受月或日部分为0的日期。
如果使用IGNORE选项,我们为类似的日期插入'0000-00-00'。
在非严格模式,可以接受该日期,但会生成警告。
4 NO_ZERO_DATE
在严格模式,不要将 '0000-00-00'做为合法日期。你仍然可以用IGNORE选项插入零日期。
在非严格模式,可以接受该日期,但会生成警告。
5 ERROR_FOR_DIVISION_BY_ZERO
在严格模式,在INSERT或UPDATE过程中,如果被零除(或MOD(X, 0)),则产生错误(否则为警告)。
如果未给出该模式,被零除时MySQL返回NULL。
如果用到INSERT IGNORE或UPDATE IGNORE中,MySQL生成被零除警告,但操作结果为NULL。
6 NO_AUTO_CREATE_USER
防止GRANT自动创建新用户,除非还指定了密码。
7 NO_ENGINE_SUBSTITUTION
如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,
用默认的存储引擎替代,并抛出一个异常。
mysq5.6 和 mysql5.7 orderBy + groupBy 表现的区别
mysql5.7 Derived table:
Derived table是自查询的一种处理形式,在5.7之前的版本,
都是把Derived table进行生成,然后以临时表的形式保存,然后进行join等形式查询.
但是5.7之后,对Derved table做了新特性处理,允许符合条件的自查询直接和副查询进行join等操作.
造成的问题:
需求: 现在需要查询一个表中按照name分组之后数据查询id最大的那条记录进行返回
select * from
(select * from tableName where xxx order by id desc) as a
group by name order by id desc limit 4;
mysql5.6写法:
实现结果: 取表中按照name分组之后数据,取每一组中id最大的那条记录,对最终结果按照id进行倒叙排列,取4条记录
mysql5.7:
实现结果: 取表中按照name分组之后,取第一条id记录,之后对最终结果按照id排序取4条
我们发现自查询中的order by id desc没有生效,少了一个 DERIVED 操作估计是内部优化了,
认为 ORDER BY 在这种语法中可忽略有 LIMIT 限制涉及排序后的结果,
不会忽略 ORDER BY,可以达到预期
解决办法:
select * from
(select * from tableName where xxx order by id desc limit xxx) as a
group by name order by id desc limit 4;
or 对自查询使用distinct处理,总之对结果集处理
不要让服务认为order by是可以优化的 增加limit之后则无法使用优化条件,则会达到预期
optimizer_switch 介绍
SHOW VARIABLES LIKE 'optimizer_switch'; 查看优化器的一些参数
index_merge=on: 允许使用索引合并优化。
介绍: 是否能使用多索引的情况,多用作or或者union条件的时候,一条sql使用多个索引,
并且对多个索引的结果集进行合并
什么是Index Merge?Index Merge的限制有哪些?
如果查询中使用到了不同的索引,可以对不同索引的条件分别进行范围扫描,
然后将扫描结果合并得到最终的结果,这就是Index Merge。
限制:只能合并同一个表的索引扫描结果,不能跨表合并。此外,无法对fulltext索引进行合并
index_condition_pushdown=on: 允许下推索引条件到存储引擎层。
materialization=on: 允许物化子查询。
derived_merge=on: 允许合并派生表。