2011-04-28 56 views
4

我在此查詢,這似乎是太慢了一些問題......如何加快這個緩慢的查詢?

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 四個隊列不同類型的列不幸的是不能將其歪成一列。

該查詢爲我們提供了每個隊列表中所有等待隊列的數量。 似乎對於mysql來說太慢了,因爲它將它記錄在slow-query.log文件中

任何幫助,將不勝感激。

編輯 這裏的解釋:

+----+--------------+-------------------+------+---------------+------+---------+------+------+-------------+ 
| 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: 多一點信息,一些表幾乎15000000記錄

+2

是否在所有表上編制了「id」列? – 2011-04-28 12:39:44

+0

請提供給我們一個解釋也。 – Pentium10 2011-04-28 12:45:33

+0

這些'QueueX'表或視圖(或別的東西)? – 2011-04-28 13:13:57

回答

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 

UPDATE

你也應該考慮通常與分區相關parallelizationpartitioning

其他好處還包括那些在下面的列表。這些功能目前尚未在MySQL分區中實現,但在我們的優先級列表中處於首位。

涉及集合函數(如SUM()和COUNT()的查詢可以很容易地並行化。這種查詢的一個簡單例子可能是SELECT salesperson_id, COUNT(orders) as order_total FROM sales GROUP BY salesperson_id;。通過「並行化」,我們的意思是可以在每個分區上同時運行查詢,並且僅通過對所有分區獲得的結果求和即可獲得最終結果。

+0

@ Pentium10,爲什麼count(*)會比count(id)更快? – Johan 2011-04-28 12:55:28

+1

http://www.mysqlperformanceblog.com/2007/04/10/count-vs-countcol/ – Pentium10 2011-04-28 13:00:47

+0

因此,看起來只有在列'空'時纔會產生任何影響,並且只有在OP從你的鏈接中沒有任何'where'子句,因爲它可以使用緩存值。有什麼理由可以在這種情況下做出改變? – 2011-04-28 13:15:34

0

確保每個表格中都有id的索引。

使用count(*)而不是count(id)。結果與結果中id中沒有空值相同,但不需要檢查空值。

+0

它似乎沒有加快查詢...很難說,因爲查詢是從來沒有相同的速度......這真的是最好的方法來從4個表中獲得計數的SUM? – TheSquad 2011-04-28 13:35:24

+0

那麼,這就是可以做的關於查詢。雖然這看起來很慢。我只是測試了總結了SQL Server中9500萬條記錄中30個查詢的計數,並且運行時間不到一秒。 – Guffa 2011-04-28 14:07:20