Author Topic: bad reputation for script  (Read 534 times)

0 Members and 1 Guest are viewing this topic.

Offline stuckwithcodeTopic starter

  • Enthusiast
  • Posts: 76
    • View Profile
bad reputation for script
« on: March 17, 2010, 08:30:38 AM »
I am trying to randomly order a mysql table and then echo the results.  Why is it that everything I read about order by rand() says that It is too slow and not to use it.

Can any help explain why or maybe offer up some other suggestions.  The table will have a lot of rows eventually


Thanks

Offline neil.johnson

  • Guru
  • Fanatic
  • *
  • Posts: 3,416
  • Gender: Male
    • View Profile
Re: bad reputation for script
« Reply #1 on: March 17, 2010, 09:31:38 AM »
This quite clearly explains why using RAND() for large result sets is a bad idea.
http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/
Using your script to randomise the data is much more efficient. For instance, if you have 100 records in your table and the primary keys are ordered correctly 1 - 100 then I can use php to give me x numbers between 1 and 100. So if I wanted 5 random records from my table:
Code: [Select]
<?php
$randoms 
= array();
$required 5;
// get me 5 numbers between 1 - 100
for($x 0$x $required$x++) {
// generate number
$number rand(1,100);
// have we already used this number?
if(!in_array($number,$randoms)) {
$randoms[] = $number;
}
// yes, try again
else {
$x--;
}
}
// run query
$result mysql_query("SELECT * FROM tablename WHERE primarykey IN(".implode(",",$randoms).")");
?>

Quote
To start, press any key. Where's the 'Any' key?

Offline stuckwithcodeTopic starter

  • Enthusiast
  • Posts: 76
    • View Profile
Re: bad reputation for script
« Reply #2 on: March 17, 2010, 11:05:08 AM »
what does the IN mean after primarykey, I half understand the code

thanks

Offline neil.johnson

  • Guru
  • Fanatic
  • *
  • Posts: 3,416
  • Gender: Male
    • View Profile
Re: bad reputation for script
« Reply #3 on: March 17, 2010, 11:35:20 AM »
It means give me any record where the primary key value is one of the supplied values i.e
If this is your table, lets call it 'users':

id | name
=======
1 Joe
2 Neil
3 Adam

Then the following would give me the first and last record
Code: [Select]
SELECT name FROM users WHERE id IN(1,3)
Quote
To start, press any key. Where's the 'Any' key?

Offline stuckwithcodeTopic starter

  • Enthusiast
  • Posts: 76
    • View Profile
Re: bad reputation for script
« Reply #4 on: March 17, 2010, 12:04:50 PM »
okay thanks a lot for the help, just to clarify, what do you consider to be a large table?

how many rows?

THanks

Offline stuckwithcodeTopic starter

  • Enthusiast
  • Posts: 76
    • View Profile
Re: bad reputation for script
« Reply #5 on: March 17, 2010, 12:14:23 PM »
also could you check your script I cant get it to randomise a table and print it, im also using the table you showed in your example

Offline neil.johnson

  • Guru
  • Fanatic
  • *
  • Posts: 3,416
  • Gender: Male
    • View Profile
Re: bad reputation for script
« Reply #6 on: March 17, 2010, 12:36:50 PM »
Quote
okay thanks a lot for the help, just to clarify, what do you consider to be a large table?
how many rows?
Doesn't really matter about the number of rows. More of a concern is what the table is being used for and the number of queries that run on it at a given time.
also could you check your script I cant get it to randomise a table and print itim also using the table you showed in your example
The script is not a complete working example. The code prior to the database query is valid and produces an array of random numbers between 1 and 100 however you will have to add the parts to connect to your database, run the query and loop over the results to print them.
You should be able to do this yourself.
Quote
To start, press any key. Where's the 'Any' key?

Offline stuckwithcodeTopic starter

  • Enthusiast
  • Posts: 76
    • View Profile
Re: bad reputation for script
« Reply #7 on: March 17, 2010, 12:39:03 PM »
Right this I can do, thanks for all the help.  One last thing I under stand the IN() thing but cannot find any guides on it on google etc. can you provide any links, thanks

Offline neil.johnson

  • Guru
  • Fanatic
  • *
  • Posts: 3,416
  • Gender: Male
    • View Profile
Quote
To start, press any key. Where's the 'Any' key?

Offline stuckwithcodeTopic starter

  • Enthusiast
  • Posts: 76
    • View Profile
Re: bad reputation for script
« Reply #9 on: March 17, 2010, 12:58:11 PM »
thanks, why can i not put a variable in IN(), the code below does not work so i just put the variable in after doing the implode e.g.

$result = mysql_query("SELECT * FROM tablename WHERE primarykey IN(".implode(",",$randoms).")");

$randomslist = implode(",", $randoms);


$result = mysql_query("SELECT * FROM tablename WHERE primarykey IN($randomslist)");

Thanks, Im nearly there

Offline stuckwithcodeTopic starter

  • Enthusiast
  • Posts: 76
    • View Profile
Re: bad reputation for script
« Reply #10 on: March 17, 2010, 01:09:15 PM »
The last post I typed was untrue the variable does work but if i have IN(101,110,102)

it prints rows 101,102,110 when i want the order to be 101,110,102

any ideas

Offline neil.johnson

  • Guru
  • Fanatic
  • *
  • Posts: 3,416
  • Gender: Male
    • View Profile
Re: bad reputation for script
« Reply #11 on: March 17, 2010, 01:30:04 PM »
Use ORDER BY in your query
Code: [Select]
SELECT * FROM tablename WHERE id IN(101,110,102) ORDER BY id ASC
Quote
To start, press any key. Where's the 'Any' key?

Offline ajlisowski

  • Enthusiast
  • Posts: 109
    • View Profile
Re: bad reputation for script
« Reply #12 on: March 17, 2010, 05:39:57 PM »
The problem is he wants it to NOT order by...which, off the top of my head I have no idea how to accomplish that...

Offline premiso

  • Karma Chameleon
  • Staff Alumni
  • Freak!
  • *
  • Posts: 6,671
  • Gender: Female
  • effing right
    • View Profile
    • PHP Help
Re: bad reputation for script
« Reply #13 on: March 17, 2010, 06:19:05 PM »
The only way to do that, afaik, is to handle it on the php end:

$result mysql_query("SELECT * FROM tablename WHERE primarykey IN(".implode(",",$randoms).")");
while (
$row mysql_fetch_assoc($result)) {
    
$rows[$row['primarykey']] = $row;
}

foreach (
$randoms as $key) {
    
print_r($rows[$key]);
}


Something like that would work.