Текущее время: Пн, авг 04 2025, 12:32

Часовой пояс: UTC + 3 часа


Правила форума


ВНИМАНИЕ!

Вопросы по SAP Query и Quick View - сюда



Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
 Заголовок сообщения: delete adjacent duplicates VS distinct
СообщениеДобавлено: Чт, янв 31 2008, 17:22 
Ассистент
Ассистент
Аватара пользователя

Зарегистрирован:
Ср, окт 24 2007, 18:23
Сообщения: 46
Откуда: Красногорск
Что предпочтительнее для унижтожения дублирующих записей после простой выборки?

1й случай:
Так:
1) select
2) sort
3) delete adjacent duplicates

или так:
1) select distinct

2й случай:
Так
1) select
join
join
join
2)sort
3)delete adjacent duplicates

или так:
1)select distinct
join
join
join

В примерах по производительности рекомендуется использовать "delete adjacent duplicates" на сколько помню. В 1м случае это наверно оправдано - быстрее работать со внутренними таблицами, нежели с базой. Но как быть во 2м? Ведь из-за joinа количество данных может сильно вырости. Тогда не лучше ли использовать distinct, если он ещё на ранней стадии до joinа будет удалять повторы. Хотя тут надо смотреть как работает distinct... Гуру расскажите, distinct удаляет записи ещё до joinа или уже в конце?


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт, фев 01 2008, 08:50 
Ассистент
Ассистент

Зарегистрирован:
Ср, дек 19 2007, 09:07
Сообщения: 31
Вопрос в том, на какую часть системы приходится нагрузка.
1) distinct выполняется СУБД, следовательно, нагружается сервер БД, зато разгружаются канал связи сервера БД с сервером приложений и сервер приложений.
2) sort + delete adjacent duplicates выполняется сервером приложений, следовательно, нагружаются сервер приложений и канал связи сервера БД с сервером приложений, но разгружается сервер БД.
Т.к. сервер приложений здесь самый некритичный ресурс, его можно вообще не учитывать.
Дальше все зависит от того, насколько сократится объем данных после удаления дубликатов. Если выбирается 1000 записей, а в итоге останется только 2, имеет смысл удалить дубликаты на уровне БД. Если же их останется 900, смысла нагружать БД нет.
Кроме того, sort + delete adjacent duplicates обладает большей гибкостью по сравнению с distinct. Например, можно сравнивать не все поля, а из дубликатов оставить записи с наибольшей датой.
Ситуации, когда при удалении дубликатов значительно сокращается количество записей, достаточно редки. Таким образом, можно сказать, что в большинстве случаев sort + delete adjacent duplicates предпочтительнее.
PS: Что касается того, может ли СУБД удалять дубликаты на ранней стадии до join`а. Лично я с трудом представляю этот процесс, т.к. во многих случаях это будет либо некорректно, либо сложно. Очень сомневаюсь, что какая-нибудь СУБД так делает.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт, фев 01 2008, 13:01 
Ассистент
Ассистент
Аватара пользователя

Зарегистрирован:
Ср, окт 24 2007, 18:23
Сообщения: 46
Откуда: Красногорск
Впринципе согласен, кроме двух моментов:

1)
Wizard написал(а):
Ситуации, когда при удалении дубликатов значительно сокращается количество записей, достаточно редки.

Такие случаи сплош и рядом, если выбираем пару неключевых полей из широкой таблицы. В моём случае как раз из 1.5 тысяч осталось 15 записей, а из 1.5 миллиона 86 тысяч.

2)
Wizard написал(а):
PS: Что касается того, может ли СУБД удалять дубликаты на ранней стадии до join`а. Лично я с трудом представляю этот процесс, т.к. во многих случаях это будет либо некорректно, либо сложно. Очень сомневаюсь, что какая-нибудь СУБД так делает.

Да нет же, это было бы очень разумно, вот пример:

1 таблица c 1й записью:
a | b
5 | 10

2 таблица с 2мя записями:
a | c | d
5 | 8 | 10
5 | 8 | 11

Пусть нам нужны поля b и c, причем без дубликатов, о чём вы и сообщаем СУБД в запросе, используя select distinct b c

Если СУБД глупая она сделает так: сделает join, результат - 2 строки, после вытащит поля b,c и потом удалит дубликаты.

Если СУБД умная, она проверит какие поля мы изымаем и по каким джойним, отбросит дубликаты до joinа и потом выполнит join. Т.е. на первом шаге во второй таблице останется только одна запись и поэтому скоростью последующей работы возрастёт, так как количество записей будет меньше. Такая оптимизация кажется очень выгодной, почему нет?! Мы же явно указываем в запросе что хотим от выборки, и если мы подскажем СУБД, что нас интересуют только distinct записи, то она воспользовавшись подсказкой выкинет лишние записи ещё до joinа.

Тем более логично становится, если посмотреть на такую выборку, с которой я и столкнулся - в одной таблице 1500 записей, во второй 1500000, и количество дубликатом огромное, если их просто джойнить, получится сколько? Вот-вот.

Я бы проверил сам как быстрее: "distinct" или "delete", но в тестовом манданте нет такого объёма данных, а у клиента пока проверить не могу - и так и так милисекунды. Да и вообще, знатоки СУБД может быть подскажут по внутренней работе БД, интересно даже :)


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт, фев 01 2008, 14:22 
Ассистент
Ассистент

Зарегистрирован:
Ср, дек 19 2007, 09:07
Сообщения: 31
azrev написал(а):
1) Такие случаи сплош и рядом, если выбираем пару неключевых полей из широкой таблицы. В моём случае как раз из 1.5 тысяч осталось 15 записей, а из 1.5 миллиона 86 тысяч.

Что я могу сказать? В моей практике такое редкость.

azrev написал(а):
2)Да нет же, это было бы очень разумно, вот пример:

Если Вы хотите узнать, как в Вашем случае поступает СУБД, просто посмотрите план запроса. Там должно быть написано, что, как и в какой последовательности. Написал у себя небольшой SELECT DISTINCT. У меня сортировка и удаление записей были последним пунктом.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт, фев 01 2008, 15:15 
Ассистент
Ассистент
Аватара пользователя

Зарегистрирован:
Ср, окт 24 2007, 18:23
Сообщения: 46
Откуда: Красногорск
Wizard написал(а):
Если Вы хотите узнать, как в Вашем случае поступает СУБД, просто посмотрите план запроса. Там должно быть написано, что, как и в какой последовательности. Написал у себя небольшой SELECT DISTINCT. У меня сортировка и удаление записей были последним пунктом.

Хмм...кстати о самом простом я и не подумал :lol: Сейчас гляну.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт, фев 01 2008, 20:46 
Президент
Президент

Зарегистрирован:
Пт, апр 28 2006, 22:39
Сообщения: 2514
Откуда: North Taxolina, USA
Пол: Женский
Wizard написал(а):
azrev написал(а):
Написал у себя небольшой SELECT DISTINCT. У меня сортировка и удаление записей были последним пунктом.


Хм, интересно. А от типа базы (скажем, SQL Server vs. Oracle) это как-то зависит?


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн, фев 04 2008, 09:33 
Ассистент
Ассистент

Зарегистрирован:
Ср, дек 19 2007, 09:07
Сообщения: 31
Jelena, только от типа базы и ее настроек это и зависит.
azrev, попробую аргументировать почему СУБД не будет делать сортировку заранее. В Вашем примере предварительное удаление дубликатов даст результат, но можно придумать другие примеры, где предварительное удаление дубликатов будет пустой тратой времени. Например, если 2 таблица будет выглядеть так:
a | c | d
4 | 8 | 10
5 | 8 | 11
Во-вторых, я думаю, любая более-менее приличная СУБД позволяет написать что-то вроде:
Code:
SELECT DISTINCT T1.B, T3.C
       FROM T1
         JOIN ( SELECT DISTINCT T2.A AS A, T2.C AS C
                       FROM T2 ) AS T3 ON T3.A = T1.A

Т.е. если программист считает, что предварительное удаление дубликатов - хорошо, он может это указать в явном виде.
Жаль только, что R/3 подобные конструкции не понимает...


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн, фев 04 2008, 11:52 
Ассистент
Ассистент
Аватара пользователя

Зарегистрирован:
Ср, окт 24 2007, 18:23
Сообщения: 46
Откуда: Красногорск
Wizard написал(а):
Жаль только, что R/3 подобные конструкции не понимает...

В этом-то и дело...


Принять этот ответ
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Ahrefs [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB