views:

94

answers:

5

OK I have this query which gives me DISTINCT product_series, plus all the other fields in the table:

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

This works fine. I am also ordering by price so I can get the starting price for each series. Nice.

However today my boss told me that all the products thats are showing up from this query are of metal_type white gold And he wants to show random metal types. so I added RAND() to the order by after the ORDER BY price so that I will still get the lowest price, but a random metal in the lowest price.. here is the new query:

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()

When I run this query, MySQL completely shuts down and tells me that there are too many connections And I get a phone call from the host admin asking me what the hell I did.

I didn't believe that could be just from added RAND() to the query and I thought it had to be a coincidence. I waited a few hours after everything was fixed and ran the query again. Immediately... same issue.

So what is going on? Because I have no clue. Is there something wrong with my query?

Thanks!!!!

+1  A: 

Here's a blog post that explains the issue quite well, and workarounds:

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

And here's a similar warning against ORDER BY RAND() for MySQL, I think the cause is basically the same there:

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

richardtallent
Here's yet another blog, with various solutions:http://jan.kneschke.de/projects/mysql/order-by-rand/
Roland Bouman
+1  A: 

Using RAND() for ORDER BY is not a good idea, because it does not scale as the data increases. You can see more information on it, including two alternatives you can adapt, in my answer to this question.

OMG Ponies
A: 

Depending on the number of products in your site, that function call is going to execute once per record, potentially slowing the query down.. considerably.

The Too Many Connections error is probably due to this query blocking others while it tries to compute those numbers.

Find another way. ;)

Chris Lively
A: 

Instead, you can generate random numbers on the programming language you're using, instead of the MySQL side, as rand() is being called for each row

Clash
A: 

If you know how many records you have you can select a random record like this (this is 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();
.
.
.
Chris Denman