【问题标题】:mysql 2.5M rows slow countmysql 250万行慢计数
【发布时间】:2013-11-06 17:20:49
【问题描述】:

有一个带有id(主键)和hash(索引)的简单mysql表。其他一些列(varchar / int),但不需要对它们进行查询。

我的总表大小约为 350MB,有 250 万行。

SELECT COUNT(*) FROM table LIMIT 1;

大约需要 0.5 - 1 秒。我的 innodb 缓冲区设置为 1GB。我也尝试过变体(没有改进),例如:

SELECT COUNT(id) FROM table LIMIT 1;

SELECT COUNT(*) FROM table WHERE id > 0 LIMIT 1;

一个

SELECT * FROM table WHERE id = 'x' LIMIT 1;

将在 1 毫秒内返回(本地 mysql)。任何改善慢计数(0.5 - 1s)的技巧将不胜感激。

【问题讨论】:

    标签: mysql sql database performance database-performance


    【解决方案1】:

    您可以找到简要说明here。简而言之,innodb 必须进行全表扫描才能计算所有行(没有 where 子句,它会利用索引)。 另见this answer

    顺便说一句,我看不出在您的查询中使用 LIMIT 1 有什么意义。由于没有group by 子句,它总是返回一条记录。

    【讨论】:

    • 但是由于我只使用主键,它不应该使用内存,因为它不需要键吗?我什至在 1GB inno db 缓冲区(4gb ram 机器)上进行了测试。
    • EXPLAIN 是你的朋友。在您的语句中使用EXPLAIN SELECT ... 并验证是否使用了索引。如果没有,你可以通过SELECT COUNT(id) FROM table USE INDEX (PRIMARY)强制使用
    【解决方案2】:

    前段时间我发现,MyISAM 表使这些操作更快。但并不是所有的表和架构都可以是 MyISAM。检查您的架构,也许您可​​以将此表切换到 MyISAM。

    也使用COUNT(1) 代替COUNT(*)

    还有另一种技巧。创建触发器并将计数保存在单独的位置。创建counter_table 和以下触发器:

    DELIMITER //
    
    CREATE TRIGGER update_counter AFTER INSERT ON table_name
    FOR EACH ROW
    BEGIN
        UPDATE counter_table
        SET counter = counter + 1
    END;
    

    【讨论】:

      猜你喜欢
      • 2010-12-19
      • 1970-01-01
      • 1970-01-01
      • 2016-11-30
      • 2011-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多