2

我有一张这样的桌子。

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 上)?

4

2 回答 2

1

使查询更快的方法是使用非规范化:将当前帐户余额存储在每条记录上。要实现这一点,您必须做三件事,然后我们将看看查询的外观:

a) 在表格中添加一列:

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 = ?;
于 2011-06-30T20:45:43.027 回答
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)
于 2011-06-30T18:38:25.563 回答