MySQL CAST肯定会花很多时间

时间:2013-07-24 04:28:36

标签: mysql casting

所以我在MySQL控制台中运行以下内容作为控制测试,看看是什么阻碍了我的查询速度。

SELECT bbva_deductions.ded_code, SUBSTRING_INDEX(bbva_deductions.employee_id, '-' , -1) AS tt_emplid, 
            bbva_job.paygroup, bbva_job.file_nbr, bbva_deductions.ded_amount 
            FROM bbva_deductions 
            LEFT JOIN bbva_job 
            ON CAST(SUBSTRING_INDEX(bbva_deductions.employee_id, '-' , -1) AS UNSIGNED) = bbva_job.emplid LIMIT 500

一直运行大约需要4秒钟。 (似乎只有500行非常高)。

简单地删除连接的CAST部分会将其减少到0.01秒......

为什么到现在这么慢?我在做什么来激怒MySQL众神吗?

编辑:

这里要求的是EXPLAIN输出:

enter image description here

没有CAST:

enter image description here

EXPLAIN EXTENDED:

enter image description here

1 个答案:

答案 0 :(得分:6)

正如How MySQL Uses Indexes所述:

  

MySQL使用索引进行这些操作:

[ deletia ]
     
      
  • 在执行连接时从其他表中检索行。如果声明它们的类型和大小相同,MySQL可以更有效地使用列上的索引。在此上下文中,VARCHARCHAR如果声明为相同大小,则视为相同。例如,VARCHAR(10)CHAR(10)的大小相同,但VARCHAR(10)CHAR(15)不是。

         

    如果在没有转换的情况下无法直接比较值,则不相似列的比较可能会阻止使用索引。假设将数字列与字符串列进行比较。对于给定值,例如数字列中的1,它可能会比较字符串列中的任意数量的值,例如'1'' 1''00001''01.e1'。这排除了对字符串列的任何索引的使用。

  •   

在您的情况下,您正在尝试连接子字符串(一个表中的字符串列)和另一个表中的字符串列之间的比较。索引可以用于此操作,但是按字典顺序执行比较(即将操作数视为字符串,即使它们代表数字)。

通过显式地将一侧转换为整数,比较以数字方式执行(根据需要) - 但这需要MySQL到字符串列的implicitly convert the type,因此它无法使用该列的索引。

由于您的架构设计不当,您已经遇到了这个障碍。您应该努力确保所有列:

  1. 使用与其内容最相关的数据类型进行编码;以及

  2. 只包含一条信息 - 请参阅Is storing a delimited list in a database column really that bad?

  3. 至少,你的bbva_job.emplid应该是一个整数;并且您的bbva_deductions.employee_id应该被拆分,以便它的部分存储在单独的(适当类型)列中。使用适当的索引,您的查询将具有更高的性能。