InnoDB和count:辅助表是否可行?

时间:2014-01-04 20:10:30

标签: mysql sql performance triggers innodb

假设我在MySQL / InnoDB上有一个包含1M用户的用户表:

用户

  • userId(主键,Int)
  • status(Int)
  • 更多数据

如果我想要准确计算status = 1(表示激活帐户)的用户数量,那么大表的方法是什么,我的想法是:< / p>

usercounts

  • 状态
  • 计数

然后在TRIGGER AFTER INSERT上运行users,更新usercounts

中的适当列

这会是最好的方式吗?

PS。一个额外的小问题:由于TRIGGER AFTER UPDATEusers更改时还需要status,是否有可用的语法:

  • 涵盖TRIGGER AFTER INSERT上的TRIGGER AFTER UPDATEstatus
  • 如果count已存在,则将count增加1,否则会插入新的(status, count = 0)对?

2 个答案:

答案 0 :(得分:1)

  

这是最好的方式吗?

最佳(基于意见)或不是,但这绝对是一种可行的方式。

  

是否有可用的语法:在状态后覆盖TRIGGER AFTER INSERT和TRIGGER更新?

没有。 MySQL中没有复合触发器语法。你必须创建单独的触发器。

  

是否有可用的语法:如果计数已经存在,则将计数递增1,否则插入新的(status,count = 0)对?

是。您可以在ON DUPLICATE KEY语句中使用INSERT子句。确保statususercounts表中的PK。

现在,如果用户可以删除,即使仅用于维护目的,您也需要使用AFTER DELETE触发器覆盖它。


据说你的触发器看起来像

CREATE TRIGGER tg_ai_users
AFTER INSERT ON users
FOR EACH ROW
  INSERT INTO usercounts (status, cnt)
  VALUES (NEW.status, 1)
  ON DUPLICATE KEY UPDATE cnt = cnt + 1;

CREATE TRIGGER tg_ad_users
AFTER DELETE ON users
FOR EACH ROW
    UPDATE usercounts 
       SET cnt = cnt - 1
     WHERE status = OLD.status;

DELIMITER $$
CREATE TRIGGER tg_au_users
AFTER UPDATE ON users
FOR EACH ROW
BEGIN
  IF NOT NEW.status <=> OLD.status THEN -- proceed ONLY if status has been changed
    UPDATE usercounts 
       SET cnt = cnt - 1
     WHERE status = OLD.status;
    INSERT INTO usercounts (status, cnt) VALUES (NEW.status, 1)
    ON DUPLICATE KEY UPDATE cnt = cnt + 1;
  END IF;
END$$
DELIMITER ;

最初填充usercounts表格使用

INSERT INTO usercounts (status, cnt)
SELECT status, COUNT(*)
  FROM users
 GROUP BY status

这是 SQLFiddle 演示

答案 1 :(得分:0)

我认为您可以选择更简单的选项。

只需在您想依靠的字段中添加索引即可。

ALTER TABLE用户ADD KEY(状态);

现在选择应该非常快。

SELECT COUNT(*)FROM users WHERE status = 1