Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql如何将无字符串值与索引的varchar列进行比较?_Mysql_Performance_Indexing_Casting - Fatal编程技术网

Mysql如何将无字符串值与索引的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 = "

最近,我在下面的用例中发现了一个性能问题 在我有一个表“MyTable”和一个整型索引列“MyCode”之前 之后,我需要更改表结构,将“MyCode”列转换为VARCHAR(保留列上的索引)

然后经历了意外的延迟,执行查询的方式如下:

 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