我在这里做的是获取预订和重复的用户。这里的预订票不能打印两次。如果用户使用该记录打印票证跟踪器表更新。如果用户两次打印相同的票证,则将其标记为重复。这里的子查询是什么,返回一些标记为重复的预留ID。
SELECT t1.id AS res_id,
t1.tx_id,
t1.tx_date,
t1.bx_date,
t1.method,
t1.theater_id,
t1.showtime_id,
t1.category_id,
t1.amount,
t1.fname,
t1.status,
t1.mobile,
u.username,
t2.*
FROM `reservation` AS t1
INNER JOIN
( SELECT *
FROM `tracker`
WHERE reservation_id IN
( SELECT reservation_id
FROM `tracker`
GROUP BY reservation_id HAVING ( METHOD = 1
AND TYPE = 0
AND COUNT(*) > 1 )
OR ( METHOD = 1
AND TYPE = 1
AND COUNT(*) > 1 )
OR ( METHOD = 2
AND TYPE = 2
AND COUNT(*) > 0 )
OR ( METHOD = 3
AND TYPE = 0
AND COUNT(*) > 0 )
OR ( METHOD = 3
AND TYPE = 1
AND COUNT(*) > 1 )
OR ( METHOD = 3
AND TYPE = 3
AND COUNT(*) > 0 )) ) AS t2 ON t1.id = t2.reservation_id
INNER JOIN `users` AS u ON u.id = t2.user_id
WHERE t2.resolved = 0
AND t2.duplicate = 1
ORDER BY t2.issue_date DESC, t1.id DESC
以上查询的EXPLAIN命令。
我该怎么办?如果我索引我应该使用哪些键?如何确定要索引的键?我知道子查询减慢了我应该遵循哪些程序来消除缓慢?
答案 0 :(得分:1)
在MySQL中,exists
子查询通常比in
子查询更快。你可以试试:
SELECT t1.id AS res_id, t1.tx_id, t1.tx_date, t1.bx_date,t1.method, t1.theater_id, t1.showtime_id,
t1.category_id, t1.amount, t1.fname, t1.status, t1.mobile, u.username, t2.*
FROM `reservation` t1 INNER JOIN
(SELECT *
FROM `tracker` t
WHERE EXISTS (SELECT 1
FROM `tracker` t3
where t3.reservation_id = t.reservation_id
GROUP BY reservation_id
HAVING (METHOD = 1 AND TYPE = 0 AND COUNT(*) > 1) OR
(METHOD = 1 AND TYPE = 1 AND COUNT(*) > 1) OR
(METHOD = 2 AND TYPE = 2 AND COUNT(*) > 0) OR
(METHOD = 3 AND TYPE = 0 AND COUNT(*) > 0) OR
(METHOD = 3 AND TYPE = 1 AND COUNT(*) > 1) OR
(METHOD = 3 AND TYPE = 3 AND COUNT(*) > 0)
)
) t2
ON t1.id = t2.reservation_id INNER JOIN
`users` AS u ON u.id = t2.user_id
WHERE t2.resolved = 0 AND t2.duplicate = 1
ORDER BY t2.issue_date DESC, t1.id DESC
我注意到子查询在having
子句中使用了隐藏列。它可能没有做你期望的。通常情况下,查询会在method
子句中包含type
和group by
,或者包含max(Method)
等表达式。