2011-02-07 59 views
0

我有一張訂單表,其中包含略多於2億條記錄。對於統計數據,我需要得到三個不同的數字。第一個是在特定日期範圍內的訂單數量,然後是來自特定狀態的訂單數量,最後是特定日期範圍內指定狀態的訂單數量。前兩個查詢平均返回10-20萬條記錄,通常不到5秒。但是,我還沒有能夠得到第三個查詢在一小時內返回結果。以下是實際查詢:MySQL獲取兩個參數的計數

SELECT COUNT(*) 
    FROM orders 
WHERE order_date BETWEEN date1 AND date2; 

上面有10萬條記錄來總結,查詢需要4秒鐘。

SELECT COUNT(*) 
    FROM orders 
LEFT JOIN customers ON orders.customer_id = customers.customer_id 
    WHERE customer.state = 'PA'; 

以上有15mil記錄來總結,查詢需要5秒鐘。

(SELECT COUNT(*) 
    FROM orders 
    WHERE order_date BETWEEN date1 AND date2) 
UNION 
(SELECT COUNT(*) 
    FROM orders 
LEFT JOIN customers ON orders.customer_id=customers.customer_id 
    WHERE customer.state = 'PA'); 

以上有4500條記錄來總結,查詢需要2個小時。

是否還有另一種方法可以用於第三個查詢,使我在更合理的時間內計數?最好不到一分鐘?

+0

你能請張貼表定義,藏漢作爲EXPLAIN輸出? – 2011-02-07 20:26:41

回答

3

一起加入查詢。另外,由於您按客戶狀態進行篩選,因此請將LEFT JOIN更改爲INNER JOIN

SELECT COUNT(*) 
FROM orders 
    INNER JOIN customers ON orders.customer_id=customers.customer_id 
WHERE customer.state = 'PA' AND order_date BETWEEN date1 AND date2 
0

您的3條查詢應該是。

SELECT COUNT(*) 
    FROM orders 
WHERE order_date BETWEEN date1 AND date2; 

SELECT COUNT(*) 
     FROM orders 
INNER JOIN customers ON orders.customer_id = customers.customer_id 
    WHERE customer.state = 'PA'; 

SELECT COUNT(*) 
     FROM orders 
INNER JOIN customers ON orders.customer_id = customers.customer_id 
    WHERE customer.state = 'PA' 
     AND order_date BETWEEN date1 AND date2; 

第二屆一個可以是LEFT JOIN,但因爲你是在客戶篩選使用WHERE子句,沒有理由從左側的接合部保留任何記錄。

對於什麼是值得的,您的第三個查詢嘗試在單個查詢中返回查詢1和查詢2的計數正在緩慢運行most likely,因爲MySQL查看UNION並且變得很有趣。無論的下面應該更好地工作

SELECT "Date", COUNT(*) 
    FROM orders 
    WHERE order_date BETWEEN date1 AND date2 
UNION ALL 
SELECT "Customer", COUNT(*) 
    FROM orders 
LEFT JOIN customers ON orders.customer_id=customers.customer_id 
    WHERE customer.state = 'PA'; 

SELECT 
(SELECT COUNT(*) 
    FROM orders 
    WHERE order_date BETWEEN date1 AND date2) DateCount, 
(SELECT COUNT(*) 
    FROM orders 
LEFT JOIN customers ON orders.customer_id=customers.customer_id 
    WHERE customer.state = 'PA') CustomerCount 

(第二個返回它作爲兩列,而不是2行)