【问题标题】:Most Efficient way to compare large 'text' type values in MySQL using InnoDB engine使用 InnoDB 引擎在 MySQL 中比较大型“文本”类型值的最有效方法
【发布时间】:2017-02-10 04:38:38
【问题描述】:

我有一个这样的临时表:

CREATE TABLE `staging` (
  `created_here_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `desc_text`  TEXT NOT NULL );

目标表为:

CREATE TABLE `final_tbl` (
  `row_id` BIGINT NOT NULL AUTO_INCREMENT,
  `created_here_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `desc_text`  TEXT NOT NULL );

我只想将 desc_text 插入到 final_tbl 中,前提是它不存在。我正在考虑两种选择:

  1. 检查 staging.desc_text 是否存在于 final_tbl.desc_text 中,如果不存在则插入到 final_tbl 中
  2. 在“final_tbl”中维护一个列,该列将存储 desc_text 列的 SHA224 值。将 staging.desc_text 的 SHA224 值与最终表中的 SHA224 列进行比较,然后决定是插入还是忽略。

我想知道哪个选项会更快?

【问题讨论】:

    标签: mysql text blob innodb query-performance


    【解决方案1】:

    嗯。 . .

    创建带有索引的 SHA224 列:

    create index unq_final_tbl_sha224 on final_tbl(sha224);
    

    然后像这样进行更新:

    insert into final_tbl(desc_text, sha224)
        select *
        from (select desc_text, sha224
              from staging s
              where not exists (select 1 from final_tbl f where f.ssh224 = s.ssh224)
             ) s
        where not exists (select 1 from final_tbl f where f.desc_text = s.desc_text);
    

    子查询背后的想法是绝对确保 MySQL 在比较哈希值之前不会对比较字段的长格式有任何想法。在没有子查询的情况下使用and 可能是安全的,但上面更保守。

    【讨论】:

    • 谢谢 Gordon,如果我使用“insert ignore into final_tbl (desc_text, sha224) select desc_text, sha224 from staging”而不是你的建议。在将记录插入final_tbl时,mysql不会先检查唯一键列然后再决定,而不是比较'desc_text'列吗?
    • @abb 。 . .我在想类似的东西,但如果你有两个 不同的 desc_text 值具有相同的 sha224 值,那么第二个将不会被插入。这种哈希冲突相当罕见,但并非不可能。
    • 即使是相对较短的 MD5,也只有 9 万亿分之一的机会会出现像 9 万亿文档那样的错误命中。
    • 好点@RickJames,使用 SHA2 的机会甚至很少。依赖 SHA2 生成的唯一密钥的风险可以忽略不计。
    【解决方案2】:

    MySQL 5.7 支持生成列。

    在 desc_text 上创建一个 SHA-512 哈希字段:

    ALTER TABLE final_tbl ADD sha512 AS SHA2(desc_text, 512);
    

    并在其上添加唯一索引:

    ALTER TABLE final_tbl ADD UNIQUE (sha512);
    

    然后在重复的哈希上你会得到一个错误:

    mysql> insert into final_tbl(desc_text) values('aaa');
    ERROR 1062 (23000): Duplicate entry 'd6f644b19812e97b5d871658d6d3400ecd4787faeb9b8990c1e7608288664be7' for key 'sha512'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 2020-10-12
      • 2011-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-24
      相关资源
      最近更新 更多