Как заказать временную таблицу - PullRequest
0 голосов
/ 13 апреля 2019

В следующем запросе я хочу ORDER BY RAND () c таблицей. Когда я помещаю ORDER BY RAND () в JOIN, для выполнения запроса требуется более 5 секунд, потому что ORDER BY выполняется до GROUP BY.

UPDATE  `backlinks` as a
    JOIN (
        SELECT  b.`id` as bid
            FROM  `backlinks` b
            WHERE  b.`googlebot_id` IS NULL
              AND  b.`used_time` IS NULL
              AND  b.`campaign_id` IN (
                SELECT  `id`  FROM  `campaigns`  WHERE  `status`=true
                                      )
            GROUP BY  b.`campaign_id` 
         ) AS c  ON a.id = c.bid
    SET a.`crawler_id` = 'test'
    limit  1;

1 Ответ

1 голос
/ 13 апреля 2019

Почему вы используете группирование без функции агрегирования
если вам нужна только строка для каждого b. campaign_id, используйте некоторую функцию агрегирования, чтобы избежать непредсказуемого результата для других значений столбца и ошибки с самой последней версией db

правильная функция агрегирования может избежать потребности в заказе и ограничить 1

и для производительности вы можете избежать предложения IN для подзапроса и использовать внутреннее соединение, это даст тот же результат, но более быстрый

UPDATE `backlinks` as a
JOIN(
    SELECT min(b.`id`) as bid
    FROM `backlinks` b
    INNER JOIN (
          SELECT `id` 
          FROM `campaigns` 
          WHERE `status`=true
    ) t1 on t1.id = b.`campaign_id` 
    WHERE b.`googlebot_id` IS NULL 
    AND b.`used_time` IS NULL 
    GROUP BY b.`campaign_id`
) AS c ON a.id = c.bid
SET a.`crawler_id` = 'test'
limit 1;

В любом случае, если вы используете MySQL версии prevoius, то 5.7 вы можете использовать группирование без функции агрегирования ... и упорядочить по ... но .. оба эти фактора влияют на производительность

 UPDATE `backlinks` as a
JOIN(
    SELECT b.`id` as bid
    FROM `backlinks` b
    INNER JOIN (
          SELECT `id` 
          FROM `campaigns` 
          WHERE `status`=true
    ) t1 on t1.id = b.`campaign_id` 
    WHERE b.`googlebot_id` IS NULL 
    AND b.`used_time` IS NULL 
    GROUP BY b.`campaign_id`

) AS c ON a.id = c.bid

SET a.`crawler_id` = 'test'

limit 1;

уникальный способ повышения производительности связан с использованием объединения вместо предложения IN и надлежащим индексом столбцов обратных ссылок в таблице campaign_id

вы можете попробовать использовать order by rand и limit за пределами подзапроса, но внутри правильного внешнего подзапроса и присоединить результат к обновлению

UPDATE `backlinks` as a 
INNER JOIN  (
  select  a1.id 
  from backlinks as a1
  INNER JOIN (
     SELECT b.`id` as bid
      FROM `backlinks` b
      INNER JOIN (
            SELECT `id` 
            FROM `campaigns` 
            WHERE `status`=true
      ) t1 on t1.id = b.`campaign_id` 
      WHERE b.`googlebot_id` IS NULL 
      AND b.`used_time` IS NULL 
      GROUP BY b.`campaign_id`
  )  AS c ON a1.id = c.bid 
  ORDER BY rand()  
  limit 1  
) t on t.id = a.id 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...