繁体   English   中英

如何使用 HAVING 加速 SQL 查询

[英]How to speed up a SQL query with HAVING

我有以下查询:

SELECT u.amount_limit
     , SUM( t.amount ) AS approved 
  FROM table_transactions AS t
     , table_users AS u 
 WHERE t.uid = u.id 
   AND t.status = 1 
   AND u.status = 1 
   AND u.amount_limit != 0 
 GROUP 
    BY t.uid 
 HAVING approved >= u.amount_limit

在一个有 1000 个用户和 1000000 个事务的数据库中,大约需要 7-8 秒。

有没有办法优化/加速这个 sql 查询?

PS:我需要达到限制的用户数量和数量,我目前使用 PHP mysql_num_rows() 获得。

更新:这是表格结构

CREATE TABLE IF NOT EXISTS table_users (
  `id` varchar(32) COLLATE utf8_bin NOT NULL,
  `amount_limit` float DEFAULT NULL,
   ....
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

CREATE TABLE IF NOT EXISTS `table_transactions` (
  `id` varchar(32) COLLATE utf8_bin NOT NULL,
  `uid` varchar(32) COLLATE utf8_bin NOT NULL,
  `status` tinyint(1) NOT NULL DEFAULT '0',
  `amount` float NOT NULL DEFAULT '0',
  ....
  PRIMARY KEY (`id`),
  KEY `uid` (`uid`),
  KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

计划一:

SELECT  u.amount_limit, x.approved
    FROM ( SELECT  uid, SUM(amount) AS approved
            FROM  transactions
            WHERE  status = 1
         ) AS x
    JOIN  users AS u  ON u.id = x.uid
    WHERE  u.amount_limit != 0
      AND  u.status = 1
      AND  x.approved >= u.amount_limit 

计划 B,如果很多用户的 limit=0 或 status:= 1,可能会更快:

SELECT  u.amount_limit, 
        ( SELECT  SUM(amount) AS approved
            FROM  transactions
            WHERE  status = 1
              AND  uid = u.id 
        ) AS approved
    FROM  users AS u
    WHERE  u.amount_limit != 0
      AND  u.status = 1
      AND  approved >= u.amount_limit

两者都将从这些综合指数中受益:

users:        INDEX(status, amount_limit, id)
transactions: INDEX(status, uid, amount) 

如果iduid是像 UUID 或哈希这样的“随机”数字,则访问将是随机且缓慢的。 我提供的索引将“覆盖”,从而显着补偿问题。

建议您重新考虑 id 的设计。

对于货币值,应避免使用FLOATDOUBLE 请参阅DECIMAL(m,n)

单独索引“标志”(例如status )很少有用。 将它作为复合索引的一部分可能会很有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM