MySQL join 在两个 varchar 列上导致 CONVERT(USING utf 16)

标签 mysql

我有两个stock & prices

请有人解释为什么在内部调用 CONVERT。两个字段的类型和长度相同。

stock 包含 product_id VARCHAR(128)

prices 包含 sku VARCHAR(128)

查询:

EXPLAIN EXTENDED
SELECT * FROM prices 
JOIN stock ON prices.sku = stock.product_id;

查看 EXPLAIN 的结果,它表示 funcref

调用 SHOW WARNINGS; 返回查询

SELECT * FROM `prices`
JOIN `stock`
WHERE (
    `prices`.`sku` = CONVERT(`stock`.`product_id` USING utf16)
)

我希望解决这个问题能帮助我解决性能问题。

解释的结果是:

"id"    "select_type"   "table" "type"  "possible_keys" "key"   "key_len"   "ref"   "rows"  "filtered"  "Extra"
"1" "SIMPLE"    "stock" "ALL"   \N  \N  \N  \N  "128715"    "100.00"    ""
"1" "SIMPLE"    "prices"    "ref"   "sku_channel,sku"   "sku_channel"   "515"   "func"  "1" "100.00"    "Using index condition"

我得出的结论是,由于从 SHOW WARNINGS

返回的结果,正在调用 CONVERT

最佳答案

您不能只对不同排序规则的字符串进行简单的字符串比较。排序规则告诉 MySQL 如何评估给定字符是否等于另一个字符。但这只适用于同一个排序规则。因此,如果您尝试比较不同排序规则的字符串,MySQL 必须先将一个或另一个字符串转换为另一个字符串的排序规则,然后才能比较字符串。

这意味着在不同排序规则的字符串之间进行 JOIN 时,必须先转换每一行的字符串,甚至是字符串不匹配的行,然后才能计算 JOIN 条件。

您应该确保比较的字符串都使用相同的排序规则。

当您尝试使用 ALTER TABLE ... CHARACTER SET = ... 时,这不会更改现有列。它只会更改表的默认字符集,这只会影响您添加到表中的新列。

要将现有列更改为不同的字符集,请使用 ALTER TABLE ... CONVERT TO CHARACTER SET ...

阅读此页面中的更改字符集部分:https://dev.mysql.com/doc/refman/8.0/en/alter-table.html获取完整信息。

关于MySQL join 在两个 varchar 列上导致 CONVERT(USING utf 16),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58012100/

相关文章:

mysql - 为什么 MySQL 中的 Modulo(负数)会产生意想不到的结果?

mysql - 选择不同条件的 2 列

php - 访问 mysql 表中的所有数据时遇到问题

php - 将 html 日期选择器设置为 null

mysqlslap phpmyadmin

php - 使用php在mysql表中保存时间戳

php - 使用 Laravel Eloquent 连接同一服务器上不同数据库中的两个 MySQL 表

mysql - SQL 如何在 NOT IN 中使用多个语句

mysql - 无法在 google cloud shell 中设置 mysql

php - 我需要为mysql上的表行增量设置外键吗