Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Удалить дубли в таблице [D7, IB6.x]


Страницы:   1 2 3

Vlad ©   (2003-09-25 10:26:00) 

Доброго всем времени суток.
Есть таблица, в которой основные поля: ID (integer,уникальное), Код(integer), Дата(Date), Наименование(Varchar).
Помимо них есть еще штук 15 полей.
Нужно из таблицы удалить дублирующие записи, так, чтобы связка Код-Дата-Наименование стала уникальной.
Проблема в том что в таблице порядка 12 млн записей.
Кто нибудь подскажет наиболее быстрый алгоритм решения задачи, выполнение которого было бы <= 24 часа ?
Все перепробованные мной способы, по предварительным подсчетам, выполнялись быкак минимум трое суток.
Спасибо.


NAlexey   (2003-09-26 15:54:00) [1]

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


Vlad   (2003-09-26 15:48:00) [2]

>DenK_vrtz © (26.09.03 15:13) [52]
Уточню.
Грамотный запрос + нужныеиндексы + грамотный оптимизатор = великая сила :)


DenK_vrtz   (2003-09-26 15:13:00) [3]

Грамотный запрос + Индексы = сила!!! :-)

Был тут у меня отчет. 22 минуты выполнялся(типа, сделал попробовал). Создал три! индекса, одну вьюшку подумал-переписал.

Результат - 45 сек!


kaif   (2003-09-26 13:58:00) [4]

Конечно, мне интересен и этот результат.
Хотя исходная задача уже решена блестяще (успеть менее, чем за сутки удалить дубликаты).
Я предлагал альтернативное решение только потому что не верил в скоростную приемлемость решения Johnmen...


Vlad   (2003-09-26 13:47:00) [5]

>kaif © (26.09.03 13:44) [49]
Твой вариант с ХП я буду пробовать на выходных, посмотрим что он даст по скорости.


kaif   (2003-09-26 13:44:00) [6]

Потрясающий результат!
Johnmen, мое почтение.
Зря, видно, я стараюсь обходиться самыми примитивными запросами.


Vlad   (2003-09-26 12:25:00) [7]

>Johnmen © (26.09.03 12:08) [46]
Кстати, по поводу планов. Ведь я использую Yaffil, а там, в отличие от самого IB существенно оптимизирован алгоритм их построения. Так что наши с тобой результаты могут отличаться, если ты используешь IB


Vlad   (2003-09-26 12:18:00) [8]

Ок. Дома ради интереса попробую. В понедельник тогда отпишу.
Хотя вобщем моя цель уже достигнута. Дубли удалены. Их, кстати, как я и подозревал оказалось почти 1 млн.


Johnmen   (2003-09-26 12:08:00) [9]

>Vlad © (26.09.03 11:42)

Да, можно и так попробовать. Но у меня есть некоторые сомнения по поводу оптимизации запроса.
Вобщем, попробуй и так и со врем.табл., если будет время/желание.


Vlad   (2003-09-26 11:42:00) [10]

А зачем при этом создавать временную таблицу ?
Почему нельзя чтобы ХП просто возвращала список ID, которые принадлежат дублирующим записям ?
Тогда: DELETE FROM Table WHERE ID IN (SELECT ID FROM Хранимая_процедура)


Johnmen   (2003-09-26 11:33:00) [11]

>Vlad ©

Кстати, я тут подумал на предложениями kaif ©, и вот предлагаю попробовать такую схему (только если борьба за скорость):
1. CREATE TABLE Temp (ID INT)
2. Хр.процедура, общая схема :
DECLARE VARIABLE i1 INT
DECLARE VARIABLE v1, v2, v3, vo1, vo2, vo3 VARCHAR
vo1=""; vo2=""; vo3="";
FOR SELECT ID,f1,f2,f3 FROM Table INTO :i1,:v1,:v2,:v3
ORDER BY f1,f2,f3 DO BEGIN
IF ((v1=vo1) AND (v2=vo2) AND (v3=vo3)) THEN
INSERT INTO Temp VALUES(:i1);
vo1=v1; vo2=v2; vo3=v3;
END

3. Отрабатываем процедуру
4. DELETE FROM Table WHERE ID IN (SELECT ID FROM Temp)
5. DROP TABLE Temp

Очень интересует скорость ! :)


Johnmen   (2003-09-26 11:10:00) [12]

>Vlad © (26.09.03 10:35)

Жаль... Придется самому пробовать, когда выдастся достаточно своб.времени...:)


Vlad   (2003-09-26 10:35:00) [13]

>Johnmen © (26.09.03 10:32) [41]
К сож. YaP упорно молчит про планы :) Так уж он устроен.
Пишет только то, что использовался тот самый составной индекс.


Johnmen   (2003-09-26 10:32:00) [14]

>Vlad ©
>DenK_vrtz ©

Мужики, не смущайте меня :) Мне неловко...

>Vlad ©

Если несложно, приведи планы выполнения запросов [2] и [12].
Мне почему-то представлялось, что [12] д.б. быстрее [2]...
Но на этот вопрос дадут ответ планы.


Vlad   (2003-09-26 10:29:00) [15]

В любом случае, спасибо всем кто участвовал.
Конечно не ожидал я такого результата.
При проверке на 100 тыс. надо было видеть мое выражение лица!
Готовый к самому худшему, налил кофе, нарезал бутербродов, взял секундомер, приготовился ждать. И на тебе ! 2 секунды :)))


DenK_vrtz   (2003-09-26 10:22:00) [16]

Vlad ©, мои поздравления!
Johnmen ©, мои восхищения! Это круто!


Vlad   (2003-09-26 10:12:00) [17]

Тестировал при количестве записей - 100 тысяч.
Вобщем результаты были выше всяких похвал.
По совету Johnmen © добавил составной индекс.
Результат:
[2] - 2 сек.
[12] - 3 сек.
[27] - запрос повел себя немного странно. Загрузка ЦП - 99%, при этом обращения к жесткому диску были оч. редкими, судя по лампочке. Короче на 10-й минуте ожидания снял задачу. Чтоб убедиться проверил еще раз. Тоже самое.
А теперь, внимание, смертельный номер. Количество записей 12 МЛН.
Используется запрос [2].
Результат - 1 час 20 мин. !!!
Johnmen ©, ты - гений ! Как я сам не догадался про составной индекс ?! Без него все было на несколько порядков медленнее.


Johnmen   (2003-09-26 10:02:00) [18]

Мне интересно !!!


DenK_vrtz   (2003-09-26 09:59:00) [19]

Канэчно!!! :-) С нетерпением ждем(c)


Vlad   (2003-09-26 09:56:00) [20]

DenK_vrtz ©, Johnmen ©, kaif © и все кто участвовал.
Вам еще интересны результаты моих лабораторных опытов, касательно обсуждаемой вчера темы ?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо