I have two queries that are basically the same:
OLD “TRANSACTIONS” QUERY
SELECT t.payment_method, t.amount, t.commission
FROM `transactions` t, `member_to_group` mtg, `member` m
WHERE mtg.`group_id`='37'
AND t.`is_deleted`='No'
AND t.`member_id`=mtg.`member_id`
AND m.member_id=mtg.member_id
AND m.`is_root`='No'
AND t.`type` IN ('Payment','Credit')
NEW “PAYMENTS” QUERY
SELECT p.method, p.amount, p.commission
FROM `payments` p, `member_to_group` mtg, `member` m
WHERE mtg.`group_id`='37'
AND p.`status`='Active'
AND p.`member_id`=mtg.`member_id`
AND m.member_id=mtg.member_id
AND m.`is_root`='No'
The first from the “transactions” table, and the second from a newer table called “payments”. Basically we had one giant table for every transaction (payments, credits, charges, fees,etc) and it got out of hand because there were always a great deal of fields that weren’t used for each type — so we split the basic types up.
For some reason, despite the better organization of the newer table system (all in the same database, mind you), and the similarities between the queries, the older “transaction” query runs much faster. The “transaction” table returns the result in 0.004 seconds while the “payments” query takes 0.303. In some areas on the web application (e.g. listings for multiple groups), this translates into 40 second page load times (as opposed to under 3).
Is there a single field (or multi-field) index I might want to use? Can I further optimize the new query?
This is running on MySQL 5.0.92
EDIT 1: I currently have single-field indexes on “transactions” (transaction_id, member_id) and “payments” (id, member_id). Unfortunately I only have access to PHPMYADMIN on this particular server and the EXPLAIN output isn’t readily copyable. That said, I can see a difference on the “transaction” query in that it says “using where;using index” on the mtg table whereas the “payment” transaction simply says “using where”.
First of all i would rewrite it as :
Then, try to compare the both queries using EXPLAIN statement. This should show you where are the differences.
Next i would take a look at this line
WHERE member_to_group.group_id = '37'and make sure that i compare the columns againstINTvalue instead ofVARCHAR.. with all the fitting indexes.As for
payments.statusandmember.is_root, both columns should be indexed (AFAIK, MySQL still does not support partial indexing).I am assuming that that following columns are primary/foreign keys and indexed accordingly:
payments.member_idmember_to_group.member_idmember.member_idP.S. you could play around with order of
WHEREstatements , but i think that should be already handled by database’s internal query optimization .. but who knows , it’s mysql.update
If the
EXPLAINsays that you are not using indexes onmember_to_grouptable, then you should check the indexes that both columns ( which are used in that query ):group_idandmember_id.. at least one of them is not indexed inmember_to_group.