php - 将两个 sql 查询合并到一个查询中工作太慢

标签 php mysql sql

我想做的是创建 1 个查询 它将进行以下检查:

我在“yesnotmp”数据库​​中有 2 个表。 一个叫做msg_t,它包含所有的消息,它有很多列。我在这个查询中关心的是那两个send_timestatus,电话,sushi_sub_id

在这里我得到了昨天所有的电话,sushi_sub_id 记录。 (而且有效)

SELECT phone, sushi_sub_id FROM `yesnotmp`.`msg`
        LEFT JOIN `yesnotmp`.`msg_t` ON (`msg`.`id`=`msg_t`.`msg_id`)
        WHERE `msg_t`.`send_time` BETWEEN '2013-06-02' AND '2013-06-03' 
            AND `msg_t`.`status` = 'Failure.Provider.Connection'

我想做的是检查 retry 表有多少 phone 插入了相同的 sushi_sub_id 以及有多少没有插入't。 (这个查询需要很长时间)

SELECT 
    Sum(CASE WHEN (SELECT Count(*) FROM `retry` AS `rty` WHERE `rty`.`phone` = `msgs`.`phone` AND `rty`.`sushi_subscription_id`=`msgs`.`sushi_sub_id`) > 0 THEN 1 ELSE 0 END) AS `In_Retry`,
Sum(CASE WHEN (SELECT Count(*) FROM `retry` AS `rty` WHERE `rty`.`phone` = `msgs`.`phone` AND `rty`.`sushi_subscription_id`=`msgs`.`sushi_sub_id`) > 0 THEN 0 ELSE 1 END) AS `Not_In_Retry`
FROM 
    (SELECT phone, sushi_sub_id FROM `yesnotmp`.`msg`
        LEFT JOIN `yesnotmp`.`msg_t` ON (`msg`.`id`=`msg_t`.`msg_id`)
        WHERE `msg_t`.`send_time` BETWEEN '2013-06-02' AND '2013-06-03' 
            AND `msg_t`.`status` = 'Failure.Provider.Connection') AS `msgs`

最佳答案

我建议稍做改动...不要通过对每一列进行选择来求和,而是简单地连接并直接对它们进行计数。首先,您的 LEFT-JOIN 到 Msg_T 表但在 Msg_T 表上有一个 WHERE 子句强制它进入 INNER JOIN。

您正在寻找给定日期和状态之间的消息时间事件。为了帮助优化查询,我将在 (status, send_time) 的 MSG_T 上建立一个索引,这样它就可以直接跳转到您的“Failure.Provider.Connection”,然后直接跳转到有问题的日期范围。

现在,重试表。这可以是左连接,因为您可能永远不会有重试条目(如果我错了请纠正我)。

SELECT 
      msg_t.phone, 
      msg_t.sushi_sub_id,
      max( case when rty.phone is not null then 1 else 0 end ) as In_Retry,
      max( case when rty.phone is  null then 1 else 0 end ) as Not_In_Retry
   FROM 
      yesnotmp.msg_t msg_t
         JOIN yesnotmp.msg msg
            ON msg_t.msg_id = msg.id
            LEFT JOIN `retry` rty
               ON  msg_t.phone = rty.phone
              AND msg_t.sushi_sub_id = rty.sushi_subscription_id
   WHERE 
          msg_t.status = 'Failure.Provider.Connection'
      AND msg_t.send_time BETWEEN '2013-06-02' AND '2013-06-03' 
   GROUP BY
      msg_t.phone, 
      msg_t.sushi_sub_id

编辑——

每次编辑尝试都进行了调整,以阐明电话的 alias.field、sushi_sub_id 引用...现在,知道字段的正确表后,我将确保 msg_t 表在查询的所有 4 个部分上都有索引。

(状态、发送时间、电话、sushi_sub_id)

至于“MAX( CASE...)”。由于这是通过左连接到相应列上的重试表来完成的,如果它有任何记录(1 个或多个),则“电话”将具有有效值。如果不存在这样的记录,它将为 NULL。

关于php - 将两个 sql 查询合并到一个查询中工作太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16896258/

相关文章:

php - MYSQL 为最后 5 条不同的记录选择 5 条记录

mysql - LEFT JOIN 查询返回多个结果

sql - Oracle 过程错误 (PLS-00428)

mysql - 比信息模式更快地获取表列的方法?

php - 如何从youtube视频获取视频标签?

php - 未找到类 'Album'

php - 无法在 PHP 中使用 AJAX 处理复选框值

sql - MySQL 的 NOW() 遵循什么时区

mysql - 如何执行存储在 MySQL 变量中的查询?

sql - Group BY 有 COUNT 个,但对不包含在组中的列进行排序