2011-06-30 136 views
2

我有一個這樣的表。提高mySQL查詢的速度

CREATE TABLE `accounthistory` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `date` datetime DEFAULT NULL, 
    `change_ammount` float DEFAULT NULL, 
    `account_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
) 

它的帳戶每日充電列表。如果我需要我使用的賬戶餘額 SELECT sum(change_ammount)FROM accounthistory WHERE account_id =; 它相當快,因爲​​我在account_id列上添加了一個索引。

但現在我需要找到時間當賬戶減去去(年月日時SUM(change_ammount)< 0) 我使用這個查詢:

SELECT main.date as date from accounthistory as main 
WHERE main.account_id=484368430 
     AND (SELECT sum(change_ammount) FROM accounthistory as sub 
          WHERE sub.account_id=484368430 AND 
           sub.date < main.date)<0 
ORDER BY main.date DESC 
LIMIT 1; 

但它的工作原理很慢。你能提出一個解決方案嗎? 也許我需要一些索引(不僅在account_id上)?

回答

0
SELECT MAX(main.date) as date 
from accounthistory as main 
WHERE main.account_id=484368430 
     AND EXISTS (SELECT 1 FROM accounthistory as sub 
          WHERE sub.account_id=main.account_id AND 
           sub.date < main.date HAVING SUM(sub.change_ammount) < 0) 
1

快速查詢的方法是使用denormalization:將當前帳戶餘額存儲在每條記錄上。在實現這一目標,你必須做三件事情,然後我們再看看查詢是什麼樣子:

一)添加一個列到表:

ALTER TABLE accounthistory ADD balance float; 

B)填充新柱

UPDATE accounthistory main SET 
balance = (
    SELECT SUM(change_amount) 
    FROM accounthistory 
    where account_id = main.account_id 
    and data <= main.date 
); 

c)向填充新的行,或者a)使用觸發器,b)中使用的應用程序邏輯,或c)運行,用於將它後添加的行上述UPDATE語句,即UPDATE ... WHERE id = ?

現在查詢哪個數據庫帳戶變爲負值,這將是非常快,變成:

SELECT date 
from accounthistory 
where balance < 0 
and balance - change_amount > 0 
and account_id = ?; 
+0

謝謝。我會嘗試反規範化。 – Taras