做一个更高效的COUNT

时间:2015-02-21 22:14:54

标签: mysql sql count

我有一个页面可以加载一些高级统计信息。没什么特别的,只有5个指标。有两个特殊的查询需要加载大约5个:

+ SELECT COUNT(*) FROM mybooks WHERE book_id IS NOT NULL
+ SELECT COUNT(*) FROM mybooks WHERE is_media = 1

该表有大约500,000行。两列都已编入索引。

这些信息一直在变化,所以我不认为这里的缓存可行。有哪些技术可以加快速度?我在想:

  • 创建一个非规范化stats表,每当列更新时都会更新。
  • 通过ajax加载慢速查询(这不会加快速度,但它允许页面立即加载)。

这里有什么建议?要求是页面加载在1s内。

表格结构:

  • id(pk,autoincrementing)
  • book_id(bigint)
  • is_media(boolean)

2 个答案:

答案 0 :(得分:1)

您可以采取一些措施来加快查询速度。

  1. optimize table

  2. 上运行mybooks
  3. book_id列更改为int unsigned,允许4.2亿个值,需要4个字节而不是8个(bigint),使表格和索引更多高效。

  4. 此外,我不确定这是否有效,而不是计数(*)我只会选择where子句中的列。例如,您的第一个查询是SELECT COUNT(book_id) FROM mybooks WHERE book_id IS NOT NULL

答案 1 :(得分:1)

统计表可能是最大/最快的降压。假设您已完全控制MySQL服务器并且尚未安排作业调度来处理此问题,您可以使用mysql事件调度程序来解决此问题。正如Vlad上面提到的,你的数据会有点过时。这是一个简单的例子:

示例统计表

CREATE TABLE stats(stat VARCHAR(20) PRIMARY KEY, count BIGINT);

初始化您的值

INSERT INTO stats(stat, count)
VALUES('all_books', 0), ('media_books', 0);

创建每10分钟更新一次的活动

DELIMITER |

CREATE EVENT IF NOT EXISTS updateBookCountsEvent
ON SCHEDULE EVERY 10 MINUTE STARTS NOW()
COMMENT 'Update book counts every 10 minutes'
DO
BEGIN
    UPDATE stats
    SET count = (SELECT COUNT(*) FROM mybooks)
    WHERE stat = 'all_books';
    UPDATE stats
    SET count = (SELECT COUNT(*) FROM mybooks WHERE is_media = 1)
    WHERE stat = 'media_books';
END |

检查是否已执行

SELECT * FROM mysql.event;

没有?检查事件调度程序是否已启用

SELECT @@GLOBAL.event_scheduler;

如果它已关闭,您将在启动时使用param --event-scheduler = ON或在my.cnf中设置它。请参阅此answerdocs