TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 06-08-2008, 07:09 PM   #1 (permalink)
Jmz
The Acquainted
 
Join Date: Oct 2007
Location: Newcastle, UK
Posts: 113
Thanks: 3
Jmz is on a distinguished road
Default Order by rand()

I have a query that looks like:

Code:
SELECT * FROM tbl_gallery WHERE fld_userid = $UserID ORDER BY RAND() LIMIT 4
I've read that using rand() isn't a good idea as it takes a lot of system resources. How can I rewrite the query to do the same thing without putting too much strain on my server?
__________________
Free CSS Tutorials
Send a message via MSN to Jmz
Jmz is offline  
Reply With Quote
Old 06-09-2008, 02:34 AM   #2 (permalink)
The Contributor
 
buggabill's Avatar
 
Join Date: Jan 2008
Location: Maine, USA
Posts: 92
Thanks: 2
buggabill is on a distinguished road
Default

In order to get four random rows you could do something like the following:

php Code:
<?php
    // get all of the ids for a user
    $result = mysql_query("SELECT id FROM tbl_gallery WHERE fld_userid = $UserID");
   
    // get the number of rows returned
    $numrows = mysql_num_rows($result);
   
    //build an array of the ids returned
    $idarr = array();
   
    while ($row = mysql_fetch_assoc($result))
    {
        $idarr[] = $row(id);
    }

    // build an array with 4 randomly selected ids in it
    $selidarr = array();
   
    for ($i=0;$i<=4;$i++)
    {
        $selidarr[] = $idarr[rand(0,$numrows)];
    }
   
    //convert the array into a string for use in a query
    $selidstr = implode(",", $selidarr);
   
    // run one more query to get the final desired results
    $sql = "SELECT * FROM tbl_gallery WHERE $id IN ($selidstr)"
?>

Hope this helps!
__________________
-- Bill
"Why is it drug addicts and computer aficionados are both called users?" -Clifford Stoll
buggabill is offline  
Reply With Quote
Old 06-09-2008, 08:39 AM   #3 (permalink)
Jmz
The Acquainted
 
Join Date: Oct 2007
Location: Newcastle, UK
Posts: 113
Thanks: 3
Jmz is on a distinguished road
Default

Hi, thanks for that. I'm getting an error at the line:
Code:
$idarr[] = $row(id);
The error says:
Quote:
Fatal error: Call to undefined function: array() in /home/jmz360/public_html/play/photo/user/templates/0/gal.php on line 14
Any ideas how I fix it?
__________________
Free CSS Tutorials
Send a message via MSN to Jmz
Jmz is offline  
Reply With Quote
Old 06-09-2008, 09:11 AM   #4 (permalink)
Jmz
The Acquainted
 
Join Date: Oct 2007
Location: Newcastle, UK
Posts: 113
Thanks: 3
Jmz is on a distinguished road
Default

Hi, thanks for that. I'm getting an error at the line:
Code:
$idarr[] = $row(id);
The error says:
Quote:
Fatal error: Call to undefined function: array() in /home/jmz360/public_html/play/photo/user/templates/0/gal.php on line 14
Any ideas how I fix it?

Also, I've noticed it can generate the same number more than once, how can I stop it doing this?
__________________
Free CSS Tutorials
Send a message via MSN to Jmz
Jmz is offline  
Reply With Quote
Old 06-09-2008, 12:07 PM   #5 (permalink)
The Contributor
 
buggabill's Avatar
 
Join Date: Jan 2008
Location: Maine, USA
Posts: 92
Thanks: 2
buggabill is on a distinguished road
Default

Wow - I suck...

I wrote that real quickly on too little sleep...

Try this...

php Code:
$idarr[] = $row['id'];
__________________
-- Bill
"Why is it drug addicts and computer aficionados are both called users?" -Clifford Stoll
buggabill is offline  
Reply With Quote
Old 06-10-2008, 06:24 PM   #6 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,280
Thanks: 90
Wildhoney is on a distinguished road
Default

I can only give you the theory of how I did it. This isn't because I don't want to share it, but it has too many dependencies. What I did was the following:
  1. Generate a random number using PHP. Select from the table where the ID is more or equal to;
  2. Add that selected ID to an array and execute the first query;
  3. When we loop again, follow the same process but append IN() to the end with the previously selected IDs;
  4. Keep doing this until we get the amount we require.

As this is selecting an ID, which should be the primary key, it is a much faster select than choosing a random line from the database.
__________________
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is offline  
Reply With Quote
Old 06-10-2008, 07:13 PM   #7 (permalink)
Jmz
The Acquainted
 
Join Date: Oct 2007
Location: Newcastle, UK
Posts: 113
Thanks: 3
Jmz is on a distinguished road
Default

Thanks for the answers, I still have a few questions about how the query is actually executed.

Say I have a query that says:
Quote:
SELECT * FROM tbl_gallery WHERE fld_userid = $UserID ORDER BY RAND() LIMIT 4
I understand (from what I've read) that the database will shuffle the rows and select 4 at random, but will the WHERE clause be executed first? Would it pick the rows that meet the where criteria and then shuffle them and select the 4 or does it shuffle all the rows and select 4 and then check the where clause?
__________________
Free CSS Tutorials
Send a message via MSN to Jmz
Jmz is offline  
Reply With Quote
Old 06-10-2008, 09:01 PM   #8 (permalink)
The Frequenter
Newcomer 
 
xenon's Avatar
 
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 438
Thanks: 3
xenon is on a distinguished road
Default

It will check the condition(s) first, and then pick up 4 from the remaining rows, of course.
__________________
I have optimistic thoughts, even though sometimes (if not always) life's a bitch.
xenon is offline  
Reply With Quote
Old 06-11-2008, 02:18 PM   #9 (permalink)
The Contributor
 
buggabill's Avatar
 
Join Date: Jan 2008
Location: Maine, USA
Posts: 92
Thanks: 2
buggabill is on a distinguished road
Default

That is why it is cpu intensive. RAND() will execute every time the WHERE clause does which will once for every record that would be returned regardless of the LIMIT.

From what I gather/understand/whatever, RAND will assign a random number to all the rows that fit the criteria and then order the results by those numbers.

The full query still needs to run even though you have the LIMIT in there, because you are ordering the results. Only the top 4 will be returned.
__________________
-- Bill
"Why is it drug addicts and computer aficionados are both called users?" -Clifford Stoll
buggabill is offline  
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 06:17 AM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design