2014-11-12 2 views
0

Следующий запрос - это перегрузка моей системы. Кажется, проблема с rand(). Я видел другие сообщения, касающиеся подобных проблем, но не могу заставить их работать над этой проблемой. Он запускается на таблице строк 10M +. Я знаю, что заказ на рандов() является проблемой, но после прочтения, как представляется, вопрос автоинкрементных (items.ID) с шагом по 2 не 1.Медленное время запроса в MySQL

SELECT stores.phone, stores.storeID, stores.name, stores.ZIP, 
     stores.state,stores.city, storeID, GEOCODES.lon, GEOCODES.lat 
FROM items 
LEFT JOIN stores on stores.storeID = items.store_ID 
LEFT JOIN GEOCODES on GEOCODES.address = CONCAT(stores.address1,', ',stores.ZIP) 
WHERE stores.phone IS NOT NULL 
GROUP BY items.store_ID 
ORDER BY RAND() 
LIMIT 200 

Другая статья, что я пытался для наблюдения был How can i optimize MySQL's ORDER BY RAND() function?, но, похоже, не может понять, как его адаптировать к этому запросу. Обратите внимание, что это делается на PHP.

+0

проблема, безусловно, упорядочить по. –

+0

Не могли бы вы показать нам свой EXPLAIN EXTENDED план запроса? также ваши шоу создают таблицы – Jaylen

ответ

0

Использование RAND() в вашем запросе имеет серьезные последствия для производительности, избегая этого, это ускорит ваш запрос.

Также, поскольку вы используете php, рандомизация заказа с использованием shuffle() w/php может быть значительно более быстрой альтернативой mysql.

См: http://php.net/manual/en/function.shuffle.php

+0

Как вы можете быть уверены в утверждении 'using UNION вместо LEFT JOIN будет значительно ускорять ваш запрос? – Rahul

+0

UNION не будет быстрее, чем ПРИСОЕДИНЯЙТЕСЬ. У вас есть доказательства? –

0

если бы я тебя, я бы LIMIT, а затем ORDER BY RAND() на ограниченный запрос .. Таким образом, вы Арент потянув все и рандомизации его .. Я использовал этот точный метод ускорить мои запросы экспоненциально

SELECT * 
FROM 
( SELECT stores.phone, stores.storeID, stores.name, stores.ZIP, 
      stores.state,stores.city, storeID, GEOCODES.lon, GEOCODES.lat 
    FROM items 
    LEFT JOIN stores on stores.storeID = items.store_ID 
    LEFT JOIN GEOCODES on GEOCODES.address = CONCAT(stores.address1,', ',stores.ZIP) 
    WHERE stores.phone IS NOT NULL 
    GROUP BY items.store_ID 
    LIMIT 200 
) t 
ORDER BY RAND() 

Некоторые доказательства:

CREATE table digits as (-- a digit table with 1 million rows) 
    1000000 row(s) affected Records: 1000000 Duplicates: 0 Warnings: 0  
    1.869 sec 

SELECT * FROM digits ORDER BY RAND() LIMIT 200 
    200 row(s) returned 
    0.465 sec/0.000 sec 

SELECT * FROM (SELECT * FROM digits LIMIT 200)t ORDER BY RAND()  
    200 row(s) returned 
    0.000 sec/0.000 sec 
+0

Концепция имеет смысл, но один вопрос. Разве это не будет просто выбрать первые 200 пунктов в таблице, что приведет к искажению распределения результатов? – user2694306

+0

@ user2694306 он мог бы выбрать это, но селектор может выбрать, какие строки выбрать без ограничения по лимиту ... так что он может выбрать другие. id рекомендуем вам попробовать! также вы можете попробовать рандомизировать его в php с помощью shuffle() и затем вытащить первые 200 записей в вашем цикле foreach в качестве боковой заметки –

Смежные вопросы