Почему добавленный RAND () вызывает перегрузку MySQL? - PullRequest
1 голос
/ 05 января 2010

ОК. У меня есть этот запрос, который дает мне DISTINCT product_series плюс все остальные поля в таблице:

SELECT  pi.*
FROM    (
        SELECT  DISTINCT product_series 
        FROM    cart_product 
        ) pd
JOIN    cart_product  pi
ON      pi.product_id =
        (
        SELECT  product_id
        FROM    cart_product po
        WHERE   product_brand = "everlon" 
                AND product_type = "'.$type.'" 
                AND product_available = "yes"
                AND product_price_contact = "no"
                AND product_series != ""
                AND po.product_series = pd.product_series
        ORDER BY product_price
        LIMIT 1
        ) ORDER BY product_price

Это отлично работает. Я также заказываю по цене, чтобы получить начальную цену для каждой серии. Ницца.

Однако сегодня мой начальник сказал мне, что все продукты, которые отображаются по этому запросу, имеют metal_type белое золото И он хочет показать случайные типы металлов. поэтому я добавил RAND () к заказу после цены ORDER BY, чтобы я все еще получал самую низкую цену, но случайный металл по самой низкой цене .. вот новый запрос:

SELECT  pi.*
FROM    (
        SELECT  DISTINCT product_series 
        FROM    cart_product 
        ) pd
JOIN    cart_product  pi
ON      pi.product_id =
        (
        SELECT  product_id
        FROM    cart_product po
        WHERE   product_brand = "everlon" 
                AND product_type = "'.$type.'" 
                AND product_available = "yes"
                AND product_price_contact = "no"
                AND product_series != ""
                AND po.product_series = pd.product_series
        ORDER BY product_price, RAND()
        LIMIT 1
        ) ORDER BY product_price, RAND()

Когда я запускаю этот запрос, MySQL полностью отключается и сообщает мне, что слишком много подключений И я получаю телефонный звонок от администратора хоста, спрашивающего меня, что, черт возьми, я сделал.

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

Так что происходит? Потому что я понятия не имею. Что-то не так с моим запросом?

Спасибо !!!!

Ответы [ 5 ]

1 голос
/ 06 января 2010

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

1 голос
/ 06 января 2010

Вот сообщение в блоге, которое объясняет проблему довольно хорошо, и обходные пути:

http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/

И вот аналогичное предупреждение против ORDER BY RAND() для MySQL, я думаю, что причина там в основном та же:

http://www.webtrenches.com/post.cfm/avoid-rand-in-mysql

0 голосов
/ 06 января 2010

Если вы знаете, сколько у вас есть записей, вы можете выбрать случайную запись, подобную этой (это Perl):

$handle->Sql("SELECT COUNT(0) AS nor FROM table");
$handle->FetchRow();
$nor = $handle->Data('nor');
$rand = int(rand()*$nor)+1;
$handle->Sql("SELECT * FROM table LIMIT $rand,1");
$handle->FetchRow();
.
.
.
0 голосов
/ 06 января 2010

Вместо этого вы можете генерировать случайные числа на используемом языке программирования, а не на стороне MySQL, так как rand() вызывается для каждой строки

0 голосов
/ 06 января 2010

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

Ошибка "Слишком много подключений", вероятно, связана с тем, что этот запрос блокирует другие, пока он пытается вычислить эти числа.

Найди другой путь. ;)

...