Как эффективно найти повторяющиеся строки BLOB-объектов в MySQL? - PullRequest
5 голосов
/ 26 ноября 2008

У меня есть таблица вида

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

В столбце BLOB-объектов содержится около 160 000 строк и около 2 ГБ данных (в среднем 14 КБ на каждый блок). В другой таблице есть внешние ключи к этой таблице.

Что-то вроде 3000 сгустков идентичны. Поэтому мне нужен запрос, который даст мне таблицу повторных сопоставлений, которая позволит мне удалить дубликаты.

Наивный подход занял около часа на 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;

У меня, по другим причинам, есть таблица размеров блобов:

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 секунд.

ОК, поэтому на вопрос: Собираюсь ли я стать намного лучше, чем второй выбор? Если да, то как?

Небольшое следствие: если у меня есть таблица, в которой ключевой столбец используется очень интенсивно, а остальные должны использоваться редко, мне лучше будет добавить еще одно объединение этой таблицы, чтобы стимулировать сканирование индекса против . полное сканирование таблицы?


Xgc на #mysql@irc.freenode.net указывает, что добавление вспомогательной таблицы, подобной размерам, но с уникальным ограничением на fk может очень помочь. Немного веселья с триггерами и тем, что не может сделать это даже неплохо, чтобы быть в курсе событий.

1 Ответ

10 голосов
/ 26 ноября 2008

Вы всегда можете использовать функцию хеширования ( MD5 или SHA1 ) для своих данных и затем сравнить хэши.

Вопрос в том, можете ли вы сохранить хеши в своей базе данных?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...