如何加快这个慢查询?

时间:2011-04-28 12:37:49

标签: mysql

我的查询问题似乎太慢......

SELECT SUM(c)  FROM (
    (
        SELECT COUNT( id ) AS c
        FROM QueueOne
        WHERE id = my_id
    )
        UNION ALL (
        SELECT COUNT( id ) AS c
        FROM QueueTwo
        WHERE id = my_id
    )
        UNION ALL (
        SELECT COUNT( id ) AS c
        FROM QueueThree
        WHERE id = my_id
    )
        UNION ALL (
        SELECT COUNT( id ) AS c
        FROM QueueFour
        WHERE id = my_id
        )
) AS d

实际上非常简单: QueueOne,QueueTwo,QueueThree,QueueFour 是四个队列有不同类型的列,不幸的是不能被打成一列。

此查询为我们提供每个Queue表中所有等待队列的编号。 对于mysql来说似乎太慢了,因为它将它记录在slow-query.log文件

任何帮助都将不胜感激。

EDIT 这是解释:

+----+--------------+-------------------+------+---------------+------+---------+------+------+-------------+
| id | select_type  | table             | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+--------------+-------------------+------+---------------+------+---------+------+------+-------------+
|  1 | PRIMARY      | <derived2>        | ALL  | NULL          | NULL | NULL    | NULL |    4 |             | 
|  2 | DERIVED      | QueueOne          | ref  | ID            | ID   | 4       |      |    1 | Using index | 
|  3 | UNION        | QueueTwo          | ref  | ID            | ID   | 4       |      |    1 | Using index | 
|  4 | UNION        | QueueThree        | ref  | ID            | ID   | 4       |      |    1 | Using index | 
|  5 | UNION        | QueueFour         | ref  | ID            | ID   | 4       |      |    1 | Using index | 
| NULL | UNION RESULT | <union2,3,4,5>    | ALL  | NULL          | NULL | NULL    | NULL | NULL |             | 
+----+--------------+-------------------+------+---------------+------+---------+------+------+-------------+
6 rows in set (0.82 sec)

编辑2: 更多信息,一些表几乎 15 000 000记录

2 个答案:

答案 0 :(得分:3)

id上添加索引,然后重写为count(*)

SELECT SUM(c) 
FROM   ((SELECT COUNT(*) AS c 
         FROM   queueone 
         WHERE  id = my_id) 
        UNION ALL 
        (SELECT COUNT(*) AS c 
         FROM   queuetwo 
         WHERE  id = my_id) 
        UNION ALL 
        (SELECT COUNT(*) AS c 
         FROM   queuethree 
         WHERE  id = my_id) 
        UNION ALL 
        (SELECT COUNT(*) AS c 
         FROM   queuefour 
         WHERE  id = my_id)) AS d 

<强>更新

您还应该查看parallelizationpartitioning

通常与分区相关的其他好处包括以下列表中的那些好处。这些功能目前尚未在MySQL Partitioning中实现,但在我们的优先级列表中占据很高的位置。

可以轻松地并行化涉及SUM()和COUNT()等聚合函数的查询。这种查询的一个简单示例可能是SELECT salesperson_id, COUNT(orders) as order_total FROM sales GROUP BY salesperson_id;。通过“并行化”,我们的意思是可以在每个分区上同时运行查询,并且仅通过对所有分区获得的结果求和来获得最终结果。

答案 1 :(得分:0)

确保每个表中都有id的索引。

使用count(*)代替count(id)。结果与结果中的id中没有空值相同,但它不必检查空值。