参考:
https://blog.youkuaiyun.com/persistencegoing/article/details/92764058
https://blog.youkuaiyun.com/undefinedAuth/article/details/99291739
结论
SELECT
temp.aa,
temp.bb,
temp.cc,
MAX( temp.aa )
FROM
( SELECT DISTINCT aa, bb, cc FROM table_name ORDER BY aa DESC ) AS temp
GROUP BY
bb
如果数据量大的话,建议order by 字段加上索引
如果不加distinct,查询结果错误
原因: mysql5.7引入了derived_merge参数
简单来说,就是是否生成派生表.
derived_merge为on时会合并派生表
举个例子:
select * from (select * from a) as b
会被变成
select * from a
等于子查询没有
那完蛋了如果上方的sql不加distinct的话,mysql5.7执行派生合并,其sql 大致会变成
SELECT
aa,
bb,
cc,
MAX( aa )
FROM
table_name
GROUP BY
bb
ORDER BY
aa DESC
显而易见,结果不对
通过解析sql的执行
可以看到加上,执行过程中会有派生表,如图
相反,如果没有distinct的话 就没有派生表
如图:
这里可以将派生表,理解为子查询的临时表
derived_merge参数
上面简单说了这个参数
根据我们的业务,即需要derived_merge为off,但是不能直接设置derived_merge为off,这会导致其他的sql查询效率极低,甚至可能出错
limit和distinct 在语句中会使合并派生表功能失效,那这里为什么不使用limit呢?
- 使用limit 你得知道数据的数量级
- 当数据量过大时,mysql性能差
另外还有这些也会使其失效:
可以通过在子查询中使用任何阻止合并的构造来禁用合并,尽管这些构造对实现的影响并不明确。 防止合并的构造对于派生表和视图引用是相同的:
1.聚合函数( SUM() , MIN() , MAX() , COUNT()等)
2.DISTINCT
3.GROUP BY
4.HAVING
5.LIMIT
6.UNION或UNION ALL
7.选择列表中的子查询
8.分配给用户变量
9.仅引用文字值(在这种情况下,没有基础表)
————————————————
版权声明:本文为优快云博主「Barry是你爸」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/undefinedAuth/article/details/99291739
另外这里又牵扯出
- limit为什么性能低,那么在使用分页时怎么提高性能?
- having? 子查询和联查的性能比较?这里的子查询能否替换成联查?
后面再学习