powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите с запросом на удаление дублей
14 сообщений из 14, страница 1 из 1
Помогите с запросом на удаление дублей
    #38880260
Добрый день, помогите пожалуйста составить запрос на удаление дублирующихся записей.

Имеется база Firebird 2.5 c таблицей BLOCKLIST которая состоит из двух полей: ID - автоинкрементное поле с первичным ключем, URLNAME - varchar (255).
IDURLNAME1pupkin.com2pupkin.com3mashkin.com
В данной таблице более 2 миллионов записей, 700000 с которых дубликаты по полю URLNAME.
В результате нужно получить таблицу без дубликатов.
IDURLNAME1pupkin.com3mashkin.com
Выборка на наличие дубликатов производилась с помощью следующего SQL запроса (время выполнения запроса 16 секунд)
Код: sql
1.
select urlname from BLOCKLIST group by urlname having count(urlname) > 1


При попытке удалить дубликаты с помощью запроса
Код: sql
1.
delete from BLOCKLIST where urlname in (select urlname from BLOCKLIST group by urlname having count(*) >1)

программа выполнения запроса (IBExpert) "висит".
Скрипт на удаление дубликатов рабочий, проверено на таблице с количеством записей до 1000, работает практически моментально.
Подскажите пожалуйста что не так и как решить, возможно неграмотно написанный скрипт, большой объем данных, возможно нужно изменить сам подход - не удалять дубликаты а создать новую таблицу и внести в нее данные без дубликатов или еще чего, почему выборка дубликатов производится за 16 сек., а удаление "висит" 2 часа и без результатов?
Оптимальным вариантом будет решение наиболее быстродействующее поскольку, в дальнейшем вожможна обработка таблиц с 20 млн. записей и более.
Спасибо.
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38880263
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь ДзюрбейURLNAME - varchar (255).
Индекс по нему есть?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38880274
Нет, индекса по URLNAME нет.
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38880277
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь Дзюрбей,

почитай
http://www.ibase.ru/devinfo/updsame.htm

там общая идея изложена. Сейчас, в ФБ 2.5 уже можно процедуру не писать, если операция одноразовая, а написать execute block.
Но схема должна быть та же самая
select ...
delete...

причем, желательно чтобы select имел план PLAN SORT, а не PLAN ... ORDER.
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38880279
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь Дзюрбей,

поскольку индекса нет и вероятно он там не нужен, то выполняться этот оператор будет в любом случае долго. Я вижу два варианта написать EXECUTE BLOCK где потоки будут развёрнуты. Но при отсутствии индекса по urlname и он будет работать не быстро. Другой вариант написать такой EXECUTE BLOCK

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
EXECUTE BLOCK 
AS
BEGIN
  INSERT INTO TMP_BLOCKLIST(ID, URLNAME)
  SELECT MIN(ID), urlname 
  FROM BLOCKLIST 
  GROUP BY urlname 
  HAVING count(*) >1;

  DELETE FROM BLOCKLIST; -- вот здесь будет скапливаться мусор, потому как удалённые записи никто не читает

  INSERT INTO BLOCKLIST(ID, URLNAME)
  SELECT ID, URLNAME
  FROM TMP_BLOCKLIST; 
END



где TMP_BLOCKLIST GTT уровня транзакции
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38880283
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь Дзюрбей,

кстати самый лучший подход был бы не позволять запись дубликатов в эту таблицу изначально.
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38880288
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь ДзюрбейПри попытке удалить дубликаты с помощью запроса
Код: sql
1.
2.
delete from BLOCKLIST where urlname in (select urlname from BLOCKLIST group by 
urlname having count(*) >1)


А ты уверен, что из таблицы нужно удалить ВСЕ дубли? Может, по одной записи для каждого
URL-а стоит-таки оставить?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38880293
Dimitry SibiryakovИгорь ДзюрбейПри попытке удалить дубликаты с помощью запроса
Код: sql
1.
2.
delete from BLOCKLIST where urlname in (select urlname from BLOCKLIST group by 
urlname having count(*) >1)


А ты уверен, что из таблицы нужно удалить ВСЕ дубли? Может, по одной записи для каждого
URL-а стоит-таки оставить?..



А этот запрос так и работает, проверено на примере (в таблице было 200 записей, 15 первых добавлено в конец, из 215 записей, после выполнения осталось 200 записей, т.е. удалилось только 15 дублей)
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38880294
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь Дзюрбей,

лучше не закладываться на это поведение. В трёшке этот запрос будет работать не так как ты хочешь.
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38880296
Симонов ДенисИгорь Дзюрбей,

кстати самый лучший подход был бы не позволять запись дубликатов в эту таблицу изначально.

Таблица заполнялась методом импорта из txt файла, насколько я понял можно попробовать наново заполнить, но перед этим на поле URLNAME поставить индекс, в результате чего дубли должны автоматом отсеяться, так?
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38880307
Симонов ДенисИгорь Дзюрбей,

поскольку индекса нет и вероятно он там не нужен, то выполняться этот оператор будет в любом случае долго. Я вижу два варианта написать EXECUTE BLOCK где потоки будут развёрнуты. Но при отсутствии индекса по urlname и он будет работать не быстро. Другой вариант написать такой EXECUTE BLOCK

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
EXECUTE BLOCK 
AS
BEGIN
  INSERT INTO TMP_BLOCKLIST(ID, URLNAME)
  SELECT MIN(ID), urlname 
  FROM BLOCKLIST 
  GROUP BY urlname 
  HAVING count(*) >1;

  DELETE FROM BLOCKLIST; -- вот здесь будет скапливаться мусор, потому как удалённые записи никто не читает

  INSERT INTO BLOCKLIST(ID, URLNAME)
  SELECT ID, URLNAME
  FROM TMP_BLOCKLIST; 
END



где TMP_BLOCKLIST GTT уровня транзакции

Проверил приведенный пример EXECUTE BLOCK, в результате: время выполнения полторы минуты, но результат - в таблице остались только по одному экземпляру ранее дублировавшихся записей (те 700000), остальные, которые ранее не дублировались удалены. В принципе результат виден из текста, в TMP_BLOCKLIST копируются только дублирующиеся записи из BLOCKLIST, потом из BLOCKLIST полностью удаляются все записи и таблица заполняется данными из TMP_BLOCKLIST.
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38880364
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь Дзюрбей,

ну HAVING count(*) >1 убери будет тебе все записи без дубликатов.

Игорь ДзюрбейТаблица заполнялась методом импорта из txt файла, насколько я понял можно попробовать наново заполнить, но перед этим на поле URLNAME поставить индекс, в результате чего дубли должны автоматом отсеяться, так?

Автоматом он конечно не отсеются, а вот если будешь использовать UPDATE OR INSERT или MERGE, то можно не допустить вставки самих дубликатов.
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38889266
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может, я чего-то не догнал, но разве
Код: sql
1.
delete from BLOCKLIST where urlname in (select urlname from BLOCKLIST group by urlname having count(*) >1)


не удалит все pupkin.com, оставив только mashkin.com? А это вроде как не то, что нужно.
Можно сделать так (не проверял):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
for
select urlname from BLOCKLIST group by urlname having count(*) >1
into :Url do
begin
  select first 1 id from BLOCKLIST where urlname = :url
  into :ID;
  delete from BLOCKLIST where urlname = :url and id <> :ID;
end
...
Рейтинг: 0 / 0
Помогите с запросом на удаление дублей
    #38975876
Дмиторий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Игорь Дзюрбей,

можно следом за INSERT вставить

Код: sql
1.
2.
3.
4.
5.
INSERT INTO TMP_BLOCKLIST(ID, URLNAME)
  SELECT MIN(ID), urlname 
  FROM BLOCKLIST 
  GROUP BY urlname 
  HAVING count(*) =1;
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите с запросом на удаление дублей
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]