处理函数时的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`);