Mysql 为什么使用INT选择包含数字的Varchar索引要比使用字符串慢得多?

Mysql 为什么使用INT选择包含数字的Varchar索引要比使用字符串慢得多?,mysql,indexing,innodb,database-performance,Mysql,Indexing,Innodb,Database Performance,我有一个包含数千行的表,有一个包含数字的Varchar列。尽管讨论了为什么该列不是数字类型,但从该表中选择行显示了一种奇怪的行为 尽管该列上有一个索引,但使用数字字符串查找行要比使用整数0.54秒快0.01秒。这是什么原因?它似乎无法强制转换和使用索引的值 我是不是忽略了什么?看起来它不是在强制转换Int以将其用于索引?我是否必须给出索引使用的提示,或者是否有一个数据库开关来实现这一点?或者,如果我误解了解释输出,为什么它会慢得多 要显示示例的表格布局: CREATE TABLE `exampl

我有一个包含数千行的表,有一个包含数字的Varchar列。尽管讨论了为什么该列不是数字类型,但从该表中选择行显示了一种奇怪的行为

尽管该列上有一个索引,但使用数字字符串查找行要比使用整数0.54秒快0.01秒。这是什么原因?它似乎无法强制转换和使用索引的值

我是不是忽略了什么?看起来它不是在强制转换Int以将其用于索引?我是否必须给出索引使用的提示,或者是否有一个数据库开关来实现这一点?或者,如果我误解了解释输出,为什么它会慢得多

要显示示例的表格布局:

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不起作用的情况下对我起作用。非常感谢。