MySQL Forums
Forum List  »  Performance

Re: Please help with slow easy query
Posted by: Rick James
Date: April 29, 2009 09:44AM

You still have not shown
SHOW TABLE STATUS LIKE 'item'\G
The size of item could indicate that you don't have enough ram to cache everything, which would imply that you are hitting the disk more than you would like.

You have now presented three different flavors of the SELECT in question -- the ORDER BY changed; this could be significant. :(

Have you tried removing DISTINCT? It is probably redundant.

7000 rows returned -- The EXPLAIN implies that it is hitting 3 tables, ending with 7000 hits on the last table (item). This would be 7000 probes into the index (probably pretty well cached in the key_buffer), plus 7000 probes into the data (can't tell how well cached).

At worst, I would expect on the order of 7K disk hits, which could be roughly 7 seconds. Since your timing is better than that, I would guess that much of the data is cached.

So, what it is doing?
1. Hit the first two tables (pretty efficiently),
2. Randomly(?) fetch 7000 rows from item
3. Put those rows, plus the 4 extra fields (rub., onstock, sortorder, sortorder) in a tmp table (biggest number in the Profile)
4. Sort the rows (could not use any index, since it needed to find the rows by "id") -- this was only 70ms.

I would say that key_buffer_size = 100M is about right for your 1GB of RAM, and the table sizes. Probably no other tunables matter.

Do you need all 7000 rows? Do you need all the columns if 'item'?

One trick that _sometimes_ helps in a situation like this: Fetch the ids, then fetch the rows.
SELECT i2. * ,
     'rub.' currency,
     i2.enabled & ( i2.quantity >1 ) AS onstock
   FROM item i2,
( SELECT DISTINCT i.id
   FROM item i, category_item ic, category_childs cc
   WHERE i.id = ic.item_id
     AND ic.category_id = cc.category_id
     AND cc.parent_id =6880
   ORDER BY i.sale DESC , i.enabled DESC , cc.sortorder, ic.sortorder
) i1
WHERE i2.id = i1.id
That way the "tmp" table has less to haul around, possibly saving enough to speed up the overall query. Also, it may lead to using a MEMORY tmp table, instead of MyISAM (and possibly disk).

Aha -- `description` text -- this prevents the use of MEMORY for the tmp table.

Another tidbit -- don't use BIGINT unless your really need to. It takes 8 bytes; INT takes only 4. Smaller -> more cacheable -> fewer disk hits -> faster.

If my suggested rewrite of the query provides the desired rows, I would be quite interested to see what the Profile looks like.

Options: ReplyQuote


Subject
Views
Written By
Posted
4984
April 21, 2009 11:58PM
2306
April 22, 2009 02:10AM
2301
April 22, 2009 09:37AM
2255
April 23, 2009 12:16AM
2153
April 23, 2009 02:20AM
2132
April 25, 2009 04:34PM
2145
April 27, 2009 09:47PM
Re: Please help with slow easy query
2167
April 29, 2009 09:44AM
2135
April 30, 2009 10:54PM


Sorry, you can't reply to this topic. It has been closed.

Content reproduced on this site is the property of the respective copyright holders. It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.