На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS

Дорогие друзья! Поздравляем вас с Новым 2025 годом!

Всем удачи, успеха и благополучия!

msm.ru
! информация о разделе
user posted imageДанный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Akina
  
> Запрос на удаление дубликатов , MariaDB 10.4.30
    Всем привет!

    Встала задача удаления дубликатов строк в таблице по полю jobillicoCA_id. Ну я, долго не думая, накидал запрос:

    ExpandedWrap disabled
      DELETE FROM jobillicoCA_jobs_fixed
      WHERE id NOT IN (
          SELECT MIN(id)
          FROM jobillicoCA_jobs_fixed
          GROUP BY jobillicoCA_id
      );

    В таблице 49162 записей... Я ждал выполнение запроса порядка 10 мин. Не выдержал, сбросил, перезалил данные. Накидал, как мне показалось, более оптимизированный запрос:

    ExpandedWrap disabled
      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 сек. Меня это устроило. Работу сделал. Но сейчас захотелось еще бы более человеческие и/или более оптимизированные варианты решения подобного вопроса. Сделал вот так, но протестировать нет возможности:

    ExpandedWrap disabled
      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;

    Привильно или не? Есть какие-либо более шустрые варики?
      ExpandedWrap disabled
        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

      А, да, у тебя ж Машка... ну тогда
      ExpandedWrap disabled
        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;
      Сообщение отредактировано: Akina -
        Цитата Akina @
        А, да, у тебя ж Машка... ну тогда

        Благодарю!

        Да ещё ... а мой самый последний вариант - норм? Будет делать что должно, и не будет ли тормозить?
          Цитата Majestio @
          а мой самый последний вариант - норм?

          Нет. Просто посчитай ради любопытства, сколько пар записей вынужден будет прожевать сервер... если у тебя в таблице 50 тыс. записей и, скажем, в среднем по 10 записей с одинаковым jobillicoCA_id, так это под 300 тыс. пар получится. А если по 20, то уже полмиллиона. И так далее.

          Да и INNER JOIN без ON clause - хоть и съедается в MySQL/MariaDB без синтаксической ошибки, но всё равно моветон. Ну что мешало написать хотя бы CROSS JOIN?
            Akina, понятно. Пасип.
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0237 ]   [ 15 queries used ]   [ Generated: 20.01.25, 06:52 GMT ]