【问题标题】:How do I effectively find duplicate blob rows in MySQL?如何有效地在 MySQL 中找到重复的 blob 行?
【发布时间】:2008-11-26 05:46:43
【问题描述】:

我有一个表格

CREATE TABLE data
{
   pk INT PRIMARY KEY AUTO_INCREMENT,
   dt BLOB
};

它在 blob 列中有大约 160,000 行和大约 2GB 的数据(平均每个 blob 14kb)。另一个表有这个表的外键。

大约有 3000 个 blob 是相同的。所以我想要的是一个查询,它会给我一个重新映射表,允许我删除重复项。

简单的方法在 30-40k 行上花费了大约一个小时:

SELECT a.pk, MIN(b.pk) 
    FROM data AS a 
    JOIN data AS b
  ON a.dt=b.dt
  WHERE b.pk < a.pk
  GROUP BY a.pk;

由于其他原因,我碰巧有一个包含 blob 大小的表:

CREATE TABLE sizes
(
   fk INT,  // note: non-unique
   sz INT
   // other cols
);

通过为 fk 和另一个为 sz 建立索引,直接查询大约需要 24 秒,有 50k 行:

SELECT da.pk,MIN(db.pk) 
  FROM data AS da
  JOIN data AS db
  JOIN sizes AS sa
  JOIN sizes AS sb
  ON
        sa.size=sb.size
    AND da.pk=sa.fk
    AND db.pk=sb.fk
  WHERE
        sb.fk<sa.fk
    AND da.dt=db.dt 
  GROUP BY da.pk;

但是,这是对 da(数据表)进行全表扫描。鉴于命中率应该相当低,我认为索引扫描会更好。考虑到这一点,添加了第 3 个数据副本作为第 5 次连接以获得该数据,并丢失了大约 3 秒。

好的,问题是:我会比第二个选择好得多吗?如果是,怎么做?

一个推论是:如果我有一个表,其中键列的使用非常频繁,但其余的应该很少使用,我最好添加该表的另一个连接以鼓励索引扫描与. 全表扫描?


#mysql@irc.freenode.net 上的 Xgc 指出添加实用程序表(如大小)但对 fk 具有唯一约束可能会有很大帮助。使用触发器带来一些乐趣,而不会让它保持最新状态甚至还不错。

【问题讨论】:

    标签: mysql optimization join blob


    【解决方案1】:

    您始终可以对数据使用散列函数(MD5SHA1),然后比较散列值。

    问题是您是否可以将哈希值保存在数据库中?

    【讨论】:

    • +1:我同意这一点。如果每次查询陷入困境时都必须进行字节比较。确保添加记录的代码也对它们进行哈希处理,并为所有现有行生成哈希。现在您只需比较 blob 大小和哈希值。
    • +1:似乎是最有效的方式(至少,它会缩小您需要实际比较的 BLOB 的数量。)
    猜你喜欢
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 2020-08-18
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    相关资源
    最近更新 更多