Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.14.84] |
|
Данный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ. |
Сообщ.
#1
,
|
|
|
Всем привет!
Встала задача удаления дубликатов строк в таблице по полю jobillicoCA_id. Ну я, долго не думая, накидал запрос: DELETE FROM jobillicoCA_jobs_fixed WHERE id NOT IN ( SELECT MIN(id) FROM jobillicoCA_jobs_fixed GROUP BY jobillicoCA_id ); В таблице 49162 записей... Я ждал выполнение запроса порядка 10 мин. Не выдержал, сбросил, перезалил данные. Накидал, как мне показалось, более оптимизированный запрос: CREATE TEMPORARY TABLE temp_duplicates AS SELECT j1.* FROM jobillicoCA_jobs_fixed j1 JOIN jobillicoCA_jobs_fixed j2 ON j1.jobillicoCA_id = j2.jobillicoCA_id WHERE j1.id > j2.id; DELETE j1 FROM jobillicoCA_jobs_fixed j1 JOIN temp_duplicates td ON j1.id = td.id; Он отработал быстрее - порядка 10 сек. Меня это устроило. Работу сделал. Но сейчас захотелось еще бы более человеческие и/или более оптимизированные варианты решения подобного вопроса. Сделал вот так, но протестировать нет возможности: DELETE j1 FROM jobillicoCA_jobs_fixed j1 INNER JOIN jobillicoCA_jobs_fixed j2 WHERE j1.id > j2.id AND j1.jobillicoCA_id = j2.jobillicoCA_id; Привильно или не? Есть какие-либо более шустрые варики? |
Сообщ.
#2
,
|
|
|
WITH cte AS ( SELECT id, ROW_NUMBER() OVER (PARTITION BY jobillicoCA_id ORDER BY id ASC) rn FROM jobillicoCA_jobs_fixed ) DELETE jobillicoCA_jobs_fixed FROM jobillicoCA_jobs_fixed JOIN cte USING (id) WHERE cte.rn > 1 А, да, у тебя ж Машка... ну тогда DELETE jobillicoCA_jobs_fixed FROM jobillicoCA_jobs_fixed JOIN ( SELECT id, ROW_NUMBER() OVER (PARTITION BY jobillicoCA_id ORDER BY id ASC) rn FROM jobillicoCA_jobs_fixed ) AS cte USING (id) WHERE cte.rn > 1; |
Сообщ.
#3
,
|
|
|
Цитата Akina @ А, да, у тебя ж Машка... ну тогда Благодарю! Да ещё ... а мой самый последний вариант - норм? Будет делать что должно, и не будет ли тормозить? |
Сообщ.
#4
,
|
|
|
Цитата Majestio @ а мой самый последний вариант - норм? Нет. Просто посчитай ради любопытства, сколько пар записей вынужден будет прожевать сервер... если у тебя в таблице 50 тыс. записей и, скажем, в среднем по 10 записей с одинаковым jobillicoCA_id, так это под 300 тыс. пар получится. А если по 20, то уже полмиллиона. И так далее. Да и INNER JOIN без ON clause - хоть и съедается в MySQL/MariaDB без синтаксической ошибки, но всё равно моветон. Ну что мешало написать хотя бы CROSS JOIN? |
Сообщ.
#5
,
|
|
|
Akina, понятно. Пасип.
|