使用InnoDB引擎比较MySQL中大型“文本”类型值的最有效方法

使用InnoDB引擎比较MySQL中大型“文本”类型值的最有效方法,mysql,text,blob,innodb,query-performance,Mysql,Text,Blob,Innodb,Query Performance,我有一个这样的暂存台: 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

我有一个这样的暂存台:

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 );
我只想在不存在描述文本的情况下将其插入最终描述。我想有两个选择:

检查final_tbl.desc_文本中是否存在staging.desc_文本,如果不存在,则插入final_tbl 在“final_tbl”中维护一列,该列将存储desc_text列的SHA224值。将staging.desc_text的SHA224值与最终表格中的SHA224列进行比较,然后决定是插入还是忽略。 我想知道哪个选项更快?

创建具有索引的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在比较散列值之前不会想到比较字段的长格式。使用和不使用子查询可能是安全的,但上面的内容更为保守。

Hmmm

创建具有索引的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在比较散列值之前不会想到比较字段的长格式。使用和不使用子查询可能是安全的,但上面的内容更为保守。

MySQL 5.7支持生成列

在描述文本上创建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'

MySQL 5.7支持生成列

在描述文本上创建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'

谢谢Gordon,如果我在最终描述文本中使用insert ignore,sha224选择描述文本,而不是您的建议,请从staging中选择sha224。在将记录插入final_tbl时,mysql是否会首先检查唯一键列,然后立即做出决定,而不是比较'desc_text'列?@abb。我也在考虑类似的东西,但是如果有两个不同的desc_text值具有相同的sha224值,那么将不会插入第二个。这样的散列冲突相当罕见,但并非不可能。即使是相对较短的MD5,也只有9万亿分之一的几率会出现像9万亿文档那样的错误命中。很好的一点@RickJames,使用SHA2的几率甚至很小。依赖由SHA2生成的唯一密钥的风险可以忽略不计。感谢Gordon,如果我在最终描述文本中使用insert ignore,sha224选择描述文本,从暂存中选择sha224,而不是您的建议。在将记录插入final_tbl时,mysql是否会首先检查唯一键列,然后立即做出决定,而不是比较'desc_text'列?@abb。我也在考虑类似的东西,但是如果有两个不同的desc_text值具有相同的sha224值,那么将不会插入第二个。这样的散列冲突相当罕见,但并非不可能。即使是相对较短的MD5,也只有9万亿分之一的几率会出现像9万亿文档那样的错误命中。很好的一点@RickJames,使用SHA2的几率甚至很小。依赖SHA2生成的唯一密钥的风险可以忽略不计。