Впринципе согласен, кроме двух моментов:
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", но в тестовом манданте нет такого объёма данных, а у клиента пока проверить не могу - и так и так милисекунды. Да и вообще, знатоки СУБД может быть подскажут по внутренней работе БД, интересно даже
