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

时间:2018-11-02 17:51:41

标签: mysql utf-8 character-encoding ascii query-performance

使用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.,我可以期待任何事情。 ¯\ _(ツ)_ /¯

2 个答案:

答案 0 :(得分:1)

  

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

如果您这样做

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?

答案 1 :(得分:0)

为什么不一直使用UTF-8?使用ASCII表通常是一个错误,这是您忘记为某些内容设置编码的标志。使用单一编码可以大大简化您的内部架构。

仅当具有CHARVARCHARTEXT列时,编码才有意义。

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