这是我的表t1;它有一百万行。
CREATE TABLE `t1` (
`a` varchar(10) NOT NULL,
`b` varchar(10) DEFAULT NULL,
`c` varchar(10) DEFAULT NULL,
`d` varchar(10) DEFAULT NULL,
`e` varchar(10) DEFAULT NULL,
`f` varchar(10) DEFAULT NULL,
`g` varchar(10) DEFAULT NULL,
`h` varchar(10) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
结果:
mysql> select * from t1 where a=10000000;
Empty set (1.42 sec)
mysql> select * from t1 where b=10000000;
Empty set (1.41 sec)
为什么选择主键和普通字段一样快?
3条答案
按热度按时间w41d8nur1#
试试
select * from t1 where a='10000000';
您可能会强制MySQL将所有这些字符串转换为整数-因为整数的类型优先级高于
varchar
-在这种情况下,字符串的索引是无用的实际上,很明显,我错了。通过阅读conversions文档,我相信在MySQL中,我们最终强制将比较的双方转换为
float
,因为我看不到上面的任何要点:在所有其他情况下,参数作为浮点(真实的)数进行比较。
一个字符串和一个整数的匹配。
t1rydlwq2#
在几乎所有的数据库中,数据都存储在块中。阅读块是IO的基本单元。索引帮助系统在数据块上归零,它保存了我们试图读取的数据,并避免阅读所有的数据块。在一个非常小的表中,只有一个或很少的数据块,索引的使用实际上可能是一种开销,可以完全跳过。即使使用索引,也很少提供任何性能优势。在一张相当大的table上做同样的实验。
PS:索引和键(主键)是不可互换的概念。前者是物理的,后者是逻辑的。
oxf4rvwz3#
在你要求MySQL做的事情中有一个技术上的区别,这看起来并不重要,但实际上很重要。
这些值都存储为字符串,您已经要求MySQL查找匹配 integer 1000000的字符串。这是一个比较,它不能通过用索引查找替换比较来优化,原因如下。
为什么MySQL不能将整数1000000转换为字符串并使用索引进行查找?
因为那会要求一些微妙不同的东西。比较:
最上面的一个只要求与特定字符串匹配的值。但你要的是最下面的。
底部的一个不能被优化,因为它不是1:1的转换-有许多字符串与整数1000000进行正比较。所以MySQL需要遍历所有的值来检查每个值是否匹配。
MySQL中匹配1000000的字符串
有很多
正如你所看到的,MySQL甚至不能使用索引来缩小字符串的开头,因为潜在的匹配可能包含第一个'1'之前的字符。
为什么MySQL不改变它处理这个问题的方式?
MySQL比较字符串和数值的方式与文档中的方式一致,也与其他数据库和脚本语言比较字符串和整数或将字符串转换为整数的方式一致。
MySQL可以选择做不同的一件事是在这种上下文中不允许隐式转换,这将迫使用户在查询中使用内置的CAST-可以说这可以防止类似的事故。然而,它也会使一个相对常见的操作--数字与字符串中的数字的比较--变得更加冗长。
无论如何,在MySQL中做出的设计决策不能轻易逆转,如果这会改变现有代码的行为。
摘要
在这种情况下,用户几乎肯定会将列设置为数字列,在这种情况下,上述问题将不适用,并且通过索引查找可以轻松满足比较。
或者,他们可以要求进行字符串到字符串的比较,这也可以通过索引查找(在索引上进行适当的排序)相对容易地满足。
但是我已经在上面解释了为什么他们写的查询指定的两个不同类型之间的比较不能用索引来满足,因为有多个字符串匹配那个整数。