一尘不染

MySQL是否消除SELECT和HAVING / GROUP BY子句之间的公共子表达式

mysql

我经常看到人们用这样的查询回答MySQL问题:

SELECT DAY(date), other columns
FROM table
GROUP BY DAY(date);

SELECT somecolumn, COUNT(*)
FROM table
HAVING COUNT(*) > 1;

我一直喜欢给该列取别名,并在GROUP BYor HAVING子句中引用它,例如

SELECT DAY(date) AS day, other columns
FROM table
GROUP BY day;

SELECT somecolumn, COUNT(*) AS c
FROM table
HAVING c > 1;

MySQL是否足够聪明,可以注意到后面的子句中的表达式与中的相同SELECT,并且仅执行一次?我不确定如何测试-
EXPLAIN并没有显示任何区别,但是它似乎并没有显示出它是如何进行分组或过滤的;它似乎主要用于优化连接和WHERE子句。

我倾向于对MySQL优化感到悲观,所以我想给我所有的帮助。


阅读 214

收藏
2020-05-17

共1个答案

一尘不染

我认为可以使用sleep()函数进行测试,
例如看一下这个演示:http :
//sqlfiddle.com/#!2/0bc1b/1

Select * FROM t;

| X |
|---|
| 1 |
| 2 |
| 2 |

SELECT x+sleep(1)
FROM t
GROUP BY x+sleep(1);

SELECT x+sleep(1) As name
FROM t
GROUP BY name;

两个查询的执行时间约为3000毫秒(3秒)。
该表中有3条记录,对于每条记录,查询只hibernate1秒,
因此这意味着该表达式对每条记录仅求值一次,而不是两次。

2020-05-17