开发者社区> 问答> 正文

在MySQL中加快行计数?mysql

出于说明目的,假设您正在使用带有三列的简单MySQL“ books”表运行一个库:

(ID,标题,状态)

id是主键 书名是书的标题 status可以是描述书籍当前状态的枚举(例如,Available,Checkedout,Processing,MISSING) 一个简单的查询来报告每种状态下有多少本书:

SELECT status, COUNT(*) FROM books GROUP BY status 或专门查找有多少本书:

SELECT COUNT(*) FROM books WHERE status = "AVAILABLE" 但是,一旦表增长到数百万行,这些查询将花费几秒钟来完成。在“状态”列中添加索引似乎并没有改变我的经验。

除了在书每次更改状态时(通过触发器或其他某种机制)定期缓存结果或在单独的表中显式更新摘要信息外,是否有任何技术可以加快此类查询的速度?似乎COUNT查询最终查看了每一行,而且(不知道更多详细信息)令我有些惊讶的是,无法以某种方式从索引中确定此信息。

更新

使用具有200万行的示例表(带有索引的“状态”列),我对GROUP BY查询进行了基准测试。使用InnoDB存储引擎,查询在我的计算机上花费3.0-3.2秒。使用MyISAM,查询需要0.9-1.1秒。在两种情况下,count(*),count(status)或count(1)之间都没有显着差异。

MyISAM肯定要快一点,但是我很好奇是否有办法使等效查询运行得更快(例如10-50毫秒-足够快,可以在低流量站点的每个网页请求上调用)无需担心缓存和触发器的开销。听起来答案似乎是“没有办法快速运行直接查询”,这正是我所期望的-我只是想确保自己不会错过一个简单的选择。

展开
收起
保持可爱mmm 2020-05-17 13:27:22 450 0
1 条回答
写回答
取消 提交回答
  • 所以问题是

    有什么技术可以加快这类查询的速度吗?

    好吧,不是真的。对于那些SELECT COUNT(*)查询,基于列的存储引擎可能会更快,但是对于几乎所有其他查询,它的性能都会降低。

    最好的选择是通过触发器维护摘要表。它没有太多的开销,并且无论表有多大,SELECT部分​​都将是瞬时的。这是一些样板代码:

    DELIMITER //

    CREATE TRIGGER ai_books AFTER INSERT ON books FOR EACH ROW UPDATE books_cnt SET total = total + 1 WHERE status = NEW.status // CREATE TRIGGER ad_books AFTER DELETE ON books FOR EACH ROW UPDATE books_cnt SET total = total - 1 WHERE status = OLD.status; // CREATE TRIGGER au_books AFTER UPDATE ON books FOR EACH ROW BEGIN IF (OLD.status <> NEW.status) THEN UPDATE books_cnt SET total = total + IF(status = NEW.status, 1, -1) WHERE status IN (OLD.status, NEW.status); END IF; END //来源:stack overflow

    2020-05-17 13:32:23
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
搭建电商项目架构连接MySQL 立即下载
搭建4层电商项目架构,实战连接MySQL 立即下载
PolarDB MySQL引擎重磅功能及产品能力盛大发布 立即下载

相关镜像