3

我在这里所做的是获取重复的预订和用户。此处预订票不能打印两次。如果用户打印带有该记录的工单跟踪器表更新。如果用户两次打印同一张票,则将其标记为重复。子查询在这里做的是返回一些被标记为重复的预订 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 上述查询的命令。

在此处输入图像描述

我该怎么办?如果我索引应该使用哪些键?我如何决定要索引哪些键?我知道子查询会减慢我的速度 我应该遵循哪些程序来消除速度缓慢?

4

1 回答 1

2

在 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。它可能没有按照您的预期进行。通常,查询将在子句中包含methodand或具有诸如.typegroup bymax(Method)

于 2013-01-04T15:19:00.110 回答