Mysql 为什么使用INT选择包含数字的Varchar索引要比使用字符串慢得多?
我有一个包含数千行的表,有一个包含数字的Varchar列。尽管讨论了为什么该列不是数字类型,但从该表中选择行显示了一种奇怪的行为 尽管该列上有一个索引,但使用数字字符串查找行要比使用整数0.54秒快0.01秒。这是什么原因?它似乎无法强制转换和使用索引的值 我是不是忽略了什么?看起来它不是在强制转换Int以将其用于索引?我是否必须给出索引使用的提示,或者是否有一个数据库开关来实现这一点?或者,如果我误解了解释输出,为什么它会慢得多 要显示示例的表格布局:Mysql 为什么使用INT选择包含数字的Varchar索引要比使用字符串慢得多?,mysql,indexing,innodb,database-performance,Mysql,Indexing,Innodb,Database Performance,我有一个包含数千行的表,有一个包含数字的Varchar列。尽管讨论了为什么该列不是数字类型,但从该表中选择行显示了一种奇怪的行为 尽管该列上有一个索引,但使用数字字符串查找行要比使用整数0.54秒快0.01秒。这是什么原因?它似乎无法强制转换和使用索引的值 我是不是忽略了什么?看起来它不是在强制转换Int以将其用于索引?我是否必须给出索引使用的提示,或者是否有一个数据库开关来实现这一点?或者,如果我误解了解释输出,为什么它会慢得多 要显示示例的表格布局: CREATE TABLE `exampl
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 |
+----+-------------+---------+------+---------------+-----------+---------+-------+------+--------------------------+
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 |
+----+-------------+---------+-------+---------------+-----------+---------+------+------+--------------------------+
SELECT * FROM example WHERE stuff = CAST(200 AS CHAR);
在这里,它似乎没有将Int转换为用于查找索引的字符串:
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 |
+----+-------------+---------+------+---------------+-----------+---------+-------+------+--------------------------+
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 |
+----+-------------+---------+-------+---------------+-----------+---------+------+------+--------------------------+
SELECT * FROM example WHERE stuff = CAST(200 AS CHAR);
如下列文件所述:
对于字符串列与数字的比较,MySQL无法使用列上的索引快速查找值。如果str_col是索引字符串列,则在以下语句中执行查找时不能使用索引:
SELECT * FROM tbl_name WHERE str_col=1;
警告:如果索引的字符集不匹配,MySQL也可能跳过索引,即使两个值都是CHAR。如果以下查询不起作用:
SELECT * FROM example WHERE stuff = CAST(200 AS CHAR);
然后,通过运行“character_set_database”等show变量来获取数据库字符集;在CONVERT语句中使用它,如下所示:本例假设数据库字符集为latin1-将其替换为character_set_database的值:
由于您的列存储为varchar,搜索为字符串的速度必须更快。但它说使用index和200可以很容易地转换为字符串。注意:使用CAST200作为CHAR可能无法让MySQL使用索引。@KevinBorders:为什么不这样做?事实证明,如果字符集不匹配,可能会发生这种情况。CONVERT200使用拉丁文1为我修复了它。@KevinBorders:这很有趣。MySQL应该转码到适当的字符集。什么版本?这发生在5.6.21和latin1字符集数据库以及客户端、连接、结果和系统的其他字符集设置为utf8的情况下。Convert在CAST不起作用的情况下对我起作用。非常感谢。