【问题标题】:Reduce processing power on query降低查询的处理能力
【发布时间】:2016-06-05 22:25:37
【问题描述】:

我正在处理一个每分钟添加几次新行的表。就像我经常需要运行下面的查询一样,我认为这是最近出现延迟峰值的原因。

有什么方法可以让这个查询更有效率吗?

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 ;

【问题讨论】:

  • 你能把你在 transactions 表上定义的索引贴出来吗?
  • 添加了表结构。 :)

标签: mysql database performance processing-efficiency


【解决方案1】:

看起来你的两个表格读取查询是

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 的索引应该可以减少这种情况。

【讨论】:

    【解决方案2】:

    好的,您所经历的延迟可能不是 100% 可以预防的,但是有一个小的索引技巧可以减少这种延迟的机会:

    对您在查询中使用和/或返回的所有值使用多列索引。

    你的情况是:

    CREATE INDEX idx_nn_1 ON transactions(from_account,amount);
    CREATE INDEX idx_nn_2 ON transactions(to_account,amount);
    

    这样做的目的是确保不必读取数据库中的真实记录即可获得结果。

    有一个缺点:在多列索引中更新/插入记录比在单列索引中要慢。这里的权衡只能通过测试来确定。

    【讨论】:

      【解决方案3】:

      另外,简化查询:

      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的设置。

      【讨论】:

        猜你喜欢
        • 2014-12-25
        • 1970-01-01
        • 2020-01-29
        • 1970-01-01
        • 2011-07-30
        • 2014-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多