Mysql如何将无字符串值与索引的varchar列进行比较?
最近,我在下面的用例中发现了一个性能问题 在我有一个表“MyTable”和一个整型索引列“MyCode”之前 之后,我需要更改表结构,将“MyCode”列转换为VARCHAR(保留列上的索引) 然后经历了意外的延迟,执行查询的方式如下:Mysql如何将无字符串值与索引的varchar列进行比较?,mysql,performance,indexing,casting,Mysql,Performance,Indexing,Casting,最近,我在下面的用例中发现了一个性能问题 在我有一个表“MyTable”和一个整型索引列“MyCode”之前 之后,我需要更改表结构,将“MyCode”列转换为VARCHAR(保留列上的索引) 然后经历了意外的延迟,执行查询的方式如下: SELECT * FROM MyTable where MyCode = 1234 这个查询完全忽略了MyCode VARCHAR索引,给人的印象是它正在扫描整个表 将查询转换为 SELECT * FROM MyTable where MyCode = "
SELECT * FROM MyTable where MyCode = 1234
这个查询完全忽略了MyCode VARCHAR索引,给人的印象是它正在扫描整个表
将查询转换为
SELECT * FROM MyTable where MyCode = "1234"
性能恢复到最佳利用VARCHAR索引
所以问题是。。。。如何解释它。。。MySQL实际上是如何处理索引的。或者可能需要更改一些DB设置来避免这种情况
int_col = 1234 -- no problem; same type
char_col = "1234" -- no problem; same type
int_col = "1234" -- string is converted to number, then no problem
char_col = 1234 -- converting all the strings to numbers -- tedious
在第四种情况下,索引是无用的,因此优化器会寻找其他方法来执行查询。这可能导致“全表扫描”
主要的例外是“覆盖索引”,它只稍微快一点——包括“完整索引扫描”。我接受了里克·詹姆斯的回答,因为他抓住了重点 但是我想在做了一些测试之后再添加一些信息 问题中的情况是:当筛选列为varchar类型且提供的筛选依据值不是字符串时,MySQL实际上如何比较两个值。 如果是这种情况,您将失去利用应用于VARCHAR列的索引的机会,该索引在您的查询中会大大降低性能,而这应该是即时的和简单的 原因是MySQL前面有一个给定的值,该值的类型与 VARCHAR将执行一次完整的表扫描,并对每个记录的字段执行强制转换(varcharcol作为providedvaluetype),并将结果与提供的值进行比较 例如 具有名为“code”的VARCHAR列并进行筛选
SELECT * FROM table WHERE code=1234
完全扫描每一条记录,就像这样吗
SELECT * FROM table WHERE CAST(code as UNSIGNED)=1234
请注意,如果要针对0进行测试
SELECT * FROM table WHERE CAST(code as UNSIGNED)=0
您将返回所有具有字符串的记录,该字符串的强制转换为UNSIGNED对于mysql强制转换函数没有UNSIGNED含义。Thx,您正在确认我的假设…“将所有字符串转换为数字”。。。所以每个记录VARCHAR字段都被转换为INT以与1234进行比较?争论他们为什么不实施相反的措施。。。。将1234转换为字符串以匹配索引…第三个示例非常方便,因为它允许简单地引用所有参数替换。第四个导致
'1234xyz'=1234
和'abc'=0
。你可以说这很奇怪,但事实就是这样。
SELECT * FROM table WHERE CAST(code as UNSIGNED)=0