1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Optimizing SQL query

Discussion in 'MySQL' started by eclipse, Feb 20, 2005.

  1. #1
    Hi,

    I'd like to optimize this query:

    
    SELECT * 
    FROM `links`
    WHERE active = "1" AND mainweight != 0 ORDER BY Rand()*(1/mainweight) LIMIT 5
    
    Code (markup):
    I have a database of links wich has 3 000 rows. I'd like to select weighted random links from it (mainweight is the weight of the link). On my serwer this query is executing 0.8 sec. When i have 50-100 users on my site this is a problem.

    How can i optimize/change this query ?
     
    eclipse, Feb 20, 2005 IP
  2. expat

    expat Stranger from a far land

    Messages:
    873
    Likes Received:
    18
    Best Answers:
    0
    Trophy Points:
    0
    #2
    You ould try something like this:

    LOCK TABLES foo READ;
    SELECT FLOOR(RAND() * COUNT(*)) AS rand_row FROM foo;
    SELECT * FROM foo LIMIT $rand_row, 1;
    UNLOCK TABLES;

    Expat
     
    expat, Feb 20, 2005 IP
  3. xml

    xml Peon

    Messages:
    254
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #3
    SQL Improvements:

    only use "*" if you need all columns.

    A combined index on active AND mainweight would increase the speed of the WHERE.
     
    xml, Feb 20, 2005 IP
  4. J.D.

    J.D. Peon

    Messages:
    1,198
    Likes Received:
    65
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Test this statement in mysql (the utility) and see how long it takes. I ran a quick test and a query similar to yours returns 5 rows out of 10K in under 0.08 seconds on a regular mid-range machine. If the time you get in mysql is much less than 0.8 seconds, then most likely it's your server-side script that does something it isn't supposed to.

    If mysql reports you something close to 0.8 sec, then your database server isn't setup correctly (e.g. if you are using desktop/development setup).

    active is a boolean value and including it in any index won't do much good. Indexing mainweight isn't going to help either if its value ranges from 1 to 10 or so. Besides, this particular select statement most likely won't benefit from this index anyway because the condition is mainweight != 0, so the server would still have to sort the same result set (considering that there is no record with mainweight == 0).

    J.D.
     
    J.D., Feb 20, 2005 IP