加入3个以上表的MySQL查询需要太长时间

时间:2016-11-12 22:02:05

标签: php mysql

我有大约20个表,它们都具有如下相同的结构:

id |    date    | received_calls|answered_calls
---|----------------------------------------
 1 | 2016-11-10 |     2151      | 2021         |   
 2 | 2016-11-11 |     5201      | 5121         |
 3 | 2016-11-12 |     3333      | 2930         |

我想要做的是总和section1.received_calls + section2.received_calls + section3.received_calls .....(在代码中显示一些公式)......等等X的日期 并且在下一行再次相同,为第二天的日期。 等等。 日期对于每个表和每日顺序是唯一的,并且不能重复。

我的代码是:

SELECT
`section1`.date AS date,
(
    `section1`.received_calls + `section2`.received_calls + `section3`.received_calls
) AS received_calls,
(
    `section1`.answered_calls + `section2`.answered_calls + `section3`.answered_calls
) AS answered_calls,
ROUND(
    (
        `section1`.answered_calls + `section2`.answered_calls + `section3`.answered_calls
    ) / (
        `section1`.received_calls + `section2`.received_calls + `section3`.received_calls
    ) * (100),2) AS ans_calls,
(
    `section1`.Abandoned_Calls + `section2`.Abandoned_Calls + `section3`.Abandoned_Calls
) AS Abandoned_Calls,
ROUND(
    (
        `section1`.abandoned_calls + `section2`.abandoned_calls + `section3`.abandoned_calls
    ) / (
        `section1`.received_calls + `section2`.received_calls + `section3`.received_calls
    ) * (100),2) AS aban_calls,
ROUND(
    (
        `section1`.`Avg_Speed_Ans` + `section2`.`Avg_Speed_Ans` + `section3`.`Avg_Speed_Ans`
    ) / (
        `section1`.received_calls + `section2`.received_calls + `section3`.received_calls
    ) * (100),2) AS `Avg_Speed_Ans`
FROM
    `section1`
JOIN `section2` ON `section1`.date = `section2`.date,
 `section3`
GROUP BY
    `section1`.date

问题是它工作正常,但非常慢,可能需要3个小时才能完成(并且每个表的行数少于800行),并且我已将索引编入i&i #39; m使用上面。并将主键设置为每个表的ID列。

2 个答案:

答案 0 :(得分:1)

尝试将表格分解为子查询。例如:

Select t.date, t.calls + u.calls + v.calls allcalls from (select date, sum(calls) as calls from table1 where date=dateiwant group by date) as t ,
(select date, sum(calls) as calls from table2 where date=dateiwant group by date) as u ,
(select date, sum(calls) as calls from table3 where date=dateiwant group by date) as v
Where t.date = u.date
And u.date = v.date

答案 1 :(得分:1)

  

我有大约20个表,它们都具有如下相同的结构

您的数据库未规范化 - 第一次失败。

您是否在此处阅读了有关查询性能的许多问题?您是否注意到哪些评论被评价,哪些被投票赞成?

您尚未提供表的索引,但尚未提供查询的解释计划。您尚未提供在联接中使用的属性的基数。

  

可能需要3个小时才能完成(每个表的行数少于800行)

这意味着日期属性不是唯一的,即使在3小时后,你得到的结果也是错误的 - 它是部分笛卡尔积。

这会更快,并给你一个有效的答案:

SELECT `date`, SUM(answered_calls), SUM(received_calls)
, SUM(abandoned_calls), /* add in your formulas.... */
FROM
(
SELECT `date`, answered_calls, received_calls, abandoned_calls
FROM section1
UNION ALL
SELECT `date`, answered_calls, received_calls, abandoned_calls
FROM section2
UNION ALL
SELECT `date`, answered_calls, received_calls, abandoned_calls
FROM section3
) AS ilv
GROUP BY ilv.`date`

然而,这可以为您提供错误问题的正确答案。它应该受到日期范围的限制,并且只能使用单个表格。