我有一个包含数千行的表,其中包含一个包含数字的Varchar列。尽管讨论了为什么这个列不是数字类型,但是从该表中选择行显示出一种奇怪的行为。
虽然该列上有索引,但使用数字字符串查找行比使用Ints(0.54秒)快得多(0.01秒)。这是什么原因?似乎无法转换和使用索引的值...
我忽略了什么吗?看起来它没有强制转换为将其用于索引?我是否必须提供有关索引使用的提示,或者是否有数据库切换来完成此操作?或者,如果我误解了Explain输出,为什么它会慢得多?
表格布局以显示示例:
CREATE TABLE `example` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`stuff` varchar(45) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_stuff` (`stuff`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
这里使用字符串作为索引:
explain select * from example where stuff='200';
----+-------------+---------+------+---------------+-----------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+-----------+---------+-------+------+--------------------------+
| 1 | SIMPLE | example | ref | idx_stuff | idx_stuff | 137 | const | 1 | Using where; Using index |
+----+-------------+---------+------+---------------+-----------+---------+-------+------+--------------------------+
这里看起来它没有将Int转换为String来用于查找索引:
explain select * from example where stuff=200;
+----+-------------+---------+-------+---------------+-----------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+-----------+---------+------+------+--------------------------+
| 1 | SIMPLE | example | index | idx_stuff | idx_stuff | 137 | NULL | 2 | Using where; Using index |
+----+-------------+---------+-------+---------------+-----------+---------+------+------+--------------------------+
答案 0 :(得分:10)
如the manual中所述:
为了比较字符串列和数字,MySQL不能使用列上的索引来快速查找值。如果
str_col
是索引字符串列,则在以下语句中执行查找时无法使用索引:SELECT * FROM tbl_name WHERE str_col=1;原因是有许多不同的字符串可能会转换为
1
值,例如'1'
,' 1'
或'1a'
。
如有必要,您可以始终将CAST
整数设置为字符串,以便利用索引:
SELECT * FROM example WHERE stuff = CAST(200 AS CHAR);