需要搜索表foo
foo 结构为
id |东西
字段INDEX
中有一个something
我要搜索“ INT之间”:
SELECT CAST(something as INT) as something_int FROM foo foo_1
WHERE something_int > 1 AND something_int < 9999
在这种情况下,索引将被使用还是损坏?
答案 0 :(得分:1)
WHERE some_varchar BETWEEN '1' AND '2000' -- fast but probably incorrect
WHERE some_varchar BETWEEN 1 AND 2000 -- slow but correct
WHERE some_int BETWEEN '1' AND '2000' -- fast
WHERE some_int BETWEEN 1 AND 2000 -- fast (same as previous)
发生了什么事?
VARCHAR
中对一组数字进行排序,然后想知道列表为何乱序的问题相同:1,10,11,...,19,2, 20,...,29,3,... CAST()
只是我在这里谈论的隐式转换的显式版本。CAST('2000' TO INT)
是在“编译时”完成的,因此优化程序将其视为简单的2000
(数字,无函数调用)。some_varchar >= 1
变成了CAST(some_varchar TO INT) >= 1
。答案 1 :(得分:0)
否,将不使用索引。
CREATE TABLE foo(something varchar(20) primary key) engine=myisam;
INSERT INTO foo VALUES ('1|abc'), ('3456|def');
DESCRIBE SELECT * FROM foo WHERE CAST(something as INT) BETWEEN 1 AND 2000;
+------+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| 1 | SIMPLE | tt | index | NULL | PRIMARY | 82 | NULL | 2 | Using where; Using index |
+------+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
DESCRIBE SELECT * FROM foo WHERE something BETWEEN '1' AND '2000';
+------+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| 1 | SIMPLE | tt | range | PRIMARY | PRIMARY | 82 | NULL | 1 | Using where; Using index |
+------+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
请注意,第一个查询的possible_keys
是NULL
(而发现的rows
是2
)。
注意:即使查询的字符集与索引的字符集不匹配,也会发生这种情况。
创建一个单独的INT索引(例如,使用function index语法)。