Reputation: 38
I have two large tables of users and purchases (respectively 10^6 and 10^8 rows). I'm using mySql to run the query here in the following, but it takes ages to compute! What is the best way to speed up execution? Should I use index or split the query into two queries?
CREATE TABLE user(
uID INTEGER,
countryCode varchar(2)
);
CREATE TABLE purchases(
uID INTEGER,
productID INTEGER,
price INTEGER
);
SELECT U.countryCode AS country, SUM(P.price) AS amount
FROM user U, purchases P
WHERE U.uid = P.uid
GROUP BY U.countryCode
ORDER BY U.countryCode ASC;
I guess the problem is in the Type:All. Explain gives me this:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE U ALL NULL NULL NULL NULL 9653 Using temporary; Using filesort
1 SIMPLE P ALL NULL NULL NULL NULL 97816 Using where; Using join buffer
Upvotes: 1
Views: 217
Reputation: 562300
You need these two indexes:
CREATE INDEX USER_countryCode_uid ON user(countryCode,uid);
CREATE INDEX PURCHASES_uid_price ON purchases(uid,price);
EXPLAIN then improves:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: U
type: index
possible_keys: USER_countryCode_uid
key: USER_countryCode_uid
key_len: 10
ref: NULL
rows: 10004
Extra: Using where; Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: P
type: ref
possible_keys: PURCHASES_uid_price
key: PURCHASES_uid_price
key_len: 5
ref: test.U.uID
rows: 1
Extra: Using index
PS: You should define a primary key for every table, though this is not the issue for this particular query.
Upvotes: 2
Reputation: 1083
Try this
CREATE INDEX countryCode_IDX ON USER(countryCode);
Use this Index in your query.
SELECT U.countryCode AS Country, Sum(P.Price) AS Amount FROM USER U FORCE INDEX (countryCode_IDX) LEFT JOIN Purchases P ON U.uid = P.uid GROUP BY U.countryCode ORDER BY U.countryCode ASC;
Use the foreign key index for uid column.
Upvotes: 1