无论如何要优化以下查询?

时间:2014-06-25 08:44:15

标签: mysql

我在数据库帐户,产品和用户中有三个表。我写的查询后面执行的时间太长了。无论如何都要优化以下查询?

"SELECT accounts.id AS aucID, accounts.product_id, accounts.end_time, accounts.price, accounts.win_id, 
products.id, products.title, products.ratio, users.id , users.username, users.gender, users.email, users.ip
FROM accounts, products, users
WHERE products.id
IN (
SELECT id
FROM products
WHERE accounts.product_id = id
)
AND users.id
IN (
SELECT id
FROM users
WHERE accounts.win_id = id
)
AND accounts.end_time >= '$monday'

AND accounts.end_time < '$sunday'

GROUP BY accounts.end_time"

3 个答案:

答案 0 :(得分:2)

尝试使用INNER JOIN

SELECT accounts.id AS aucID,
       accounts.product_id,
       accounts.end_time,
       accounts.price,
       accounts.win_id,
       products.id,
       products.title,
       products.ratio,
       users.id ,
       users.username,
       users.gender,
       users.email,
       users.ip
FROM accounts
INNER JOIN products ON accounts.product_id = products.id
INNER JOIN users ON accounts.win_id = users.id
WHERE accounts.end_time >= '$monday'
  AND accounts.end_time < '$sunday'
GROUP BY accounts.end_time

答案 1 :(得分:1)

为什么不简化这个 -

 SELECT 
    accounts.id AS aucID, 
    accounts.product_id, 
    accounts.end_time, 
    accounts.price, 
    accounts.win_id, 
    products.id, 
    products.title, 
    products.ratio, 
    users.id , 
    users.username, 
    users.gender, 
    users.email, 
    users.ip
 FROM accounts, products, users
 WHERE accounts.product_id = products.id
 AND accounts.win_id = users.id
 AND accounts.end_time >= '$monday'
 AND accounts.end_time < '$sunday'
 GROUP BY accounts.end_time

您还可以考虑在以下列中创建索引:

accounts.product_id 
accounts.win_id 
accounts.end_time

答案 2 :(得分:1)

您需要使用显式JOIN而不是隐式。

select 
a.id as aucID,
a.product_id ,
a.end_time,
a.price,
a.win_id,
p.id,
p.title,
p.ratio,
u.id as user_id
u.username,
u.gender,
u.email,
u.ip
from accounts a
join products p on p.id = a.product_id
join users u on u.id = a.win_id
WHERE 
a.end_time >= '$monday'
and a.end_time < '$sunday'
GROUP BY a.end_time

现在你需要索引,所以先检查

show indexes from accounts;
show indexes from accounts;
show indexes from users;

如果不添加以下索引,请检查列是否已编入索引。

alter table accounts add index product_id_idx(product_id);
alter table accounts add index win_id_idx(win_id);
alter table accounts add index end_time_idx(end_time);  
alter table products add index pid_idx(id);
alter table users add index uid_idx(id);

请注意,主键默认为索引,因此您可以避免在

上建立索引
alter table products add index pid_idx(id);
alter table users add index uid_idx(id);

如果将它们设置为主键。

此外,请确保JOINING键始终具有相同的数据类型

例如

join products p on p.id = a.product_id

p.id和a.product_id应该具有相同的数据类型ex:int

类似地

join users u on u.id = a.win_id

更改后,请参阅查询性能。