如何在MySQL中有效地找到重复的blob行?

时间:2008-11-26 05:46:44

标签: mysql optimization join blob

我有一张表格

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
);

通过为sz构建fk和另一个的索引,从中直接查询大约需要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(数据表)上进行全表扫描。鉴于命中率应该相当低,我认为索引扫描会更好。考虑到这一点,添加了第三个数据副本作为第5个连接来获得,并且丢失了大约3秒。

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

有一个必然结果:如果我有一个表,其中键列的使用非常繁重,但其余部分应该很少使用,我是否会更好地添加该表的另一个连接以鼓励索引扫描vs 。全表扫描?


#mysql@irc.freenode.net上的Xgc指出,在fk上添加类似大小但具有唯一约束的实用程序表可能会有很大帮助。一些有趣的触发器,甚至可能使它保持最新状态甚至不坏。

1 个答案:

答案 0 :(得分:10)

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

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