连接 ASCII 和 UTF-8 表会增加开销吗?

Does joining ASCII and UTF-8 tables add overhead?

许多表使用 CHARACTER SET ascii COLLATE ascii_bin 会很好,这会稍微快一些。这是一个例子:

CREATE TABLE `session` (
    `id` CHAR(64) NOT NULL,
    `created_at` INTEGER NOT NULL,
    `modified_at` INTEGER NOT NULL,
    PRIMARY KEY (`id`),
    CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `user`(`id`)
) CHARACTER SET ascii COLLATE ascii_bin;

但如果我加入:

CREATE TABLE `session_value` (
    `session_id` CHAR(64) NOT NULL,
    `key` VARCHAR(64) NOT NULL,
    `value` TEXT,
    PRIMARY KEY (`session_id`, `key`),
    CONSTRAINT FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON DELETE CASCADE
) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

会发生什么?逻辑告诉我它应该是无缝的,因为 ASCII 是 UTF-8 的子集。人性告诉我,从核心转储到屏幕上出现的消息 Follow the white rabbit.,我可以期待任何事情。 ¯\_(ツ)_/¯

为什么不是一路UTF-8?拥有 ASCII 表通常是一个错误,这是您忘记设置编码的标志。使用单一编码极大地简化了您的内部架构。

仅当您有 CHARVARCHARTEXT 列时,编码才相关。

如果您有该类型的列,则值得将其默认设置为 UTF8MB4

Does joining ASCII and UTF-8 tables add overhead?

.

如果你这样做

SELECT whatever 
  FROM session s
  JOIN session_value v 
         ON s.id = v.session_id

查询引擎必须比较 idsession_id 的许多值以满足您的查询。

如果 idsession_id 具有完全相同的数据类型,查询规划器将能够利用索引和快速比较。

但是如果它们有不同的字符集,查询规划器必须按如下方式解释您的查询。

 ...  JOIN session_value v 
         ON CONVERT(s.id USING utf8mb4) = v.session_id

当 WHERE 或 ON 条件的形式为 f(column) 时,它会使查询不可搜索:它会阻止有效的索引使用。这会影响查询性能。

在你的情况下,当你向 session_value 插入行时会出现类似的性能问题:服务器必须进行转换以检查你的外键约束。

如果这些表要投入生产,您最好为这些列使用相同的字符集。当您拥有数千行时,解决此问题比拥有数百万行要容易得多。说真的。

What makes a SQL statement sargable?