【问题标题】:How Mysql treats comparing a no string value to a indexed varchar column?Mysql 如何处理将无字符串值与索引 varchar 列进行比较?
【发布时间】:2018-07-05 09:04:57
【问题描述】:

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

 ALTER TABLE MyTable CHANGE MyCode MyCode VARCHAR(250) DEFAULT NULL

然后遇到了意外的延迟,正在执行如下查询:

 SELECT * FROM MyTable where MyCode = 1234

这个查询完全忽略了 MyCode VARCHAR 索引,印象是它正在全面扫描表

将查询转换为

 SELECT * FROM MyTable where MyCode = "1234"

性能恢复到对 VARCHAR 索引的最佳利用

所以问题是......如何解释它......实际上 MySQL 如何处理索引。或者可能需要更改一些数据库设置以避免这种情况?

【问题讨论】:

    标签: mysql performance indexing casting


    【解决方案1】:
    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
    

    在第 4 种情况下,索引是无用的,因此优化器会寻找其他方式来执行查询。这很可能导致“全表扫描”。

    主要的例外涉及“覆盖索引”,它只是稍微快一点——涉及“完整索引扫描”。

    【讨论】:

    • Thx,您正在确认我的假设...“将所有字符串转换为数字”...所以每个记录 VARCHAR 字段都转换为 INT 以与 1234 进行比较?争论为什么他们没有实现相反的......将1234转换为字符串以匹配索引......
    • 第三个例子很方便,因为它允许简单地引用所有参数替换。第 4 个导致 '1234xyz' = 1234'abc' = 0。您可以争辩说这很奇怪或其他什么,但事实就是如此。
    【解决方案2】:

    我接受了 Rick James 的回答,因为他明白了这一点。

    但我想在进行一些测试后添加更多信息。

    问题中的情况是:当过滤列是 varchar 类型并且提供的要过滤的值不是字符串时,MySQL实际上如何比较两个值。 如果是这种情况,您将失去利用应用于 VARCHAR 列的索引的机会,这会大大降低您的查询性能,而应该是直接且简单的。

    解释是 MySQL 前面的给定值具有不同的类型 VARCHAR 将执行全表扫描,并对每条记录的字段执行 CAST(varcharcol as 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
    

    你会得到一个字符串的所有记录,它的 CAST 到 UNSIGNED 对 mysql CAST 函数没有无符号含义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多