Как я могу оптимизировать этот SQL-запрос с ORDER BY RAND () - PullRequest
3 голосов
/ 24 февраля 2012

Я пытаюсь оптимизировать этот запрос, потому что база данных, с которой он работает, огромна, и хост говорит, что этот запрос вызывает серьезную нагрузку на сервер. Я читал некоторые другие ответы о том, как заменить ORDER BY RAND (), но я недостаточно знаю об SQL, чтобы адаптировать эти ответы к этому конкретному запросу. Кто-нибудь может помочь? ТИА

  SELECT COUNT( p.prod_id ) AS no_prod, s.*
    FROM product p, seller s
   WHERE s.admin_status = '1' 
     AND s.pay_status = '1' 
     AND s.sub_type != '' 
     AND p.seller_id = s.seller_id 
GROUP BY s.seller_id 
  HAVING COUNT( p.prod_id )>5 
ORDER BY RAND() 
   LIMIT 0, 4 

Ответы [ 3 ]

0 голосов
/ 24 февраля 2012

На основании http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/

SET @MAX_SELLER_ID = SELECT MAX(seller_id) FROM seller;


SELECT COUNT( p.prod_id ) AS no_prod,
       s.*

FROM (
  -- preselect a big bunch of random sellers
  SELECT DISTINCT *
  FROM seller
  WHERE seller.id IN (
    FLOOR( RAND() * @MAX_SELLER_ID )
   ,FLOOR( RAND() * @MAX_SELLER_ID )
   ,... -- repeat or generate list of random ids in your app
  )
) AS s
INNER JOIN product p

WHERE s.admin_status = '1' 
  AND s.pay_status = '1' 
  AND s.sub_type != '' 
  AND p.seller_id = s.seller_id 

GROUP BY s.seller_id 
HAVING COUNT( p.prod_id )>5 

ORDER BY RAND() 
LIMIT 0, 4;
0 голосов
/ 24 февраля 2012

Ваш SQL вызывает серьезную нагрузку из-за ORDER BY RAND(). Вы можете обратиться в Google по причинам, по которым это является проблемой, и предложили исправления того, как добиться того же эффекта другими способами.

Лучшее объяснение, которое я смог найти после некоторого поиска, пришло из сообщения об ошибке относительно этой же проблемы в системе Solaris:

ORDER BY RAND () использует сортировку файлов и не может вести себя так же быстро, как ORDER BY some_key. Это происходит потому, что когда вы используете ORDER BY RAND () то же самое, если вы пишете запрос, например: SELECT id, rand() FROM t1 ORDER BY RAND(); Это означает, что rand () будет создан для каждой строки в таблице.

0 голосов
/ 24 февраля 2012

Возможно, лучше добавить неуникальный индекс, который включает в себя поля seller.admin_status, seller.pay_status, seller.sub_type . Вы получите максимальную отдачу от своей выгоды, индексируя поля, указанные в предложении WHERE.

...