MySQL CAST肯定会花很多时间

Kir*_*gan 4 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
Run Code Online (Sandbox Code Playgroud)

它一直运行大约4秒钟.(似乎只有500行非常高).

简单地删除连接的CAST部分就减少了0.01秒......

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

编辑:

这里要求的是EXPLAIN输出:

在此输入图像描述

没有CAST:

在此输入图像描述

EXPLAIN EXTENDED:

在此输入图像描述

egg*_*yal 6

MySQL如何使用索引中所述:

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

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

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

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

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

您已经遇到了这个路障,因为您的架构设计很差.您应该努力确保所有列:

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

  2. 只包含一条信息 - 请参阅在数据库列中存储分隔列表真的那么糟糕吗?

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