我有一张这样的桌子。
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;
但它的效果很慢。你能提出一个beter解决方案吗? 也许我需要一些索引(不仅仅是在account_id上)?
答案 0 :(得分:1)
提高查询速度的方法是使用denormalization:将当前帐户余额存储在每条记录中。实现这一点,你将不得不做三件事,然后我们将看看查询的外观:
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 = ?
< / p>
现在查询以查找帐户更改为负数的数据,这将非常快,变为:
SELECT date
from accounthistory
where balance < 0
and balance - change_amount > 0
and account_id = ?;
答案 1 :(得分: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)