我正在处理一个每分钟多次添加新行的表。正如我经常需要运行下面的查询一样,我认为这是最近滞后峰值的原因。
有什么方法可以让这个查询更有效率吗?
SELECT IFNULL((SELECT SUM(amount)
FROM transactions
WHERE to_account=:account), 0) - IFNULL((SELECT SUM(amount)
FROM transactions WHERE from_account=:account), 0) as balance;
CREATE TABLE IF NOT EXISTS `transactions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`from_account` int(11) NOT NULL,
`to_account` int(11) NOT NULL,
`amount` int(11) unsigned NOT NULL,
`fee` int(11) NOT NULL DEFAULT '0'
`ip` varchar(39) DEFAULT NULL,
`time` int(10) NOT NULL,
`type` enum('CLAIM','REFERRAL','DEPOSIT','WITHDRAWAL') NOT NULL,
`is_processed` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `from_account` (`from_account`),
KEY `to_account` (`to_account`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=24099 ;
答案 0 :(得分:0)
看起来你的两个表读数是
SELECT SUM(amount)
FROM transactions
WHERE from_account = constant
和
SELECT SUM(amount)
FROM transactions
WHERE to_account = constant
第一个可以通过(from_account,amount)上的复合索引进行优化,因为它允许通过索引范围扫描来满足查询。第二个查询可以用类似的索引来满足。您可以删除from_account和to_account上的索引,用这些复合索引替换它们。
您的INSERT和SELECT查询之间仍可能存在争用。但是SELECT的索引应该减少。
答案 1 :(得分:0)
好的,您遇到的滞后可能不是100%可预防的,但有一个小的索引技巧可以减少这种滞后的机会:
对您使用的所有值使用多列索引,或在查询中返回。
在你的情况下:
CREATE INDEX idx_nn_1 ON transactions(from_account,amount);
CREATE INDEX idx_nn_2 ON transactions(to_account,amount);
这样做是要注意不必阅读数据库中的真实记录来获得结果。
有一个缺点:在多列索引中更新/插入记录比单列索引慢。这里的权衡只能通过测试确定。
答案 2 :(得分:0)
此外,简化查询:
SELECT
( SELECT IFNULL(SUM(amount), 0) FROM transactions WHERE to_account = ... ) -
( SELECT IFNULL(SUM(amount), 0) FROM transactions WHERE from_account = ... )
AS balance;
该表似乎没有变化,但检查您的innodb_buffer_pool_size
。