处理函数时的MySQL索引问题

处理函数时的MySQL索引问题,mysql,indexing,Mysql,Indexing,我在做两个问题 SELECT * FROM datedim WHERE year = YEAR(now()); 及 这里getNow()函数只返回NOW() 我的问题是,第一个是即时的,而第二个需要更长的时间。(1.xx秒) 当我执行explain命令时,第一个命令就有这个(这很好) 但这是第二个(非常糟糕) 有人能给我解释一下发生了什么事以及为什么在使用函数时,要比直接给出它花费更长的时间来做同样的事情,寻找所有年份与现在相同的日期() 这个例子很简单,但稍后我的函数将返回一个特定的日期,我

我在做两个问题

SELECT * FROM datedim WHERE year = YEAR(now());

这里getNow()函数只返回NOW()

我的问题是,第一个是即时的,而第二个需要更长的时间。(1.xx秒)

当我执行explain命令时,第一个命令就有这个(这很好)

但这是第二个(非常糟糕)

有人能给我解释一下发生了什么事以及为什么在使用函数时,要比直接给出它花费更长的时间来做同样的事情,寻找所有年份与现在相同的日期()


这个例子很简单,但稍后我的函数将返回一个特定的日期,我只想了解发生了什么。

MySQL扫描每个结果以匹配where条件,因为当您使用用户定义的函数时,MySQL不使用索引。

我的假设是MySQL知道它可以计算
YEAR()
now()
将函数转换为某个常量值,因此在对它们求值之后(在执行查询之前),它可以使用索引
dd\u year\u idx


MySQL无法对自定义函数执行相同的操作

MySQL似乎对每一行执行
getNow()
函数,每个语句只执行一次:

NOW()返回一个常量时间,指示语句开始执行的时间。(在存储的函数或触发器中,NOW()返回函数或触发器语句开始执行的时间。)这与SYSDATE()的行为不同,后者返回函数或触发器执行的确切时间

但您可以将查询更改为以下内容以获得相同的效果:

SELECT *
FROM datedim
JOIN (SELECT YEAR(getNow()) as `year`) as y
USING (`year`);

如果不知道
getNow()
的功能,很难回答,不是吗?对不起。getNow()只需执行一个RETURN NOW();我认为优化器甚至不会尝试对用户定义的函数进行索引。
+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+
| id | select_type | table   | type | possible_keys | key         | key_len | ref   | rows | Extra       |
+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+
|  1 | SIMPLE      | datedim | ref  | dd_year_idx   | dd_year_idx | 5       | const |  365 | Using where |
+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+
+----+-------------+---------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | datedim | ALL  | NULL          | NULL | NULL    | NULL | 10958 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+-------+-------------+
SELECT *
FROM datedim
JOIN (SELECT YEAR(getNow()) as `year`) as y
USING (`year`);