【问题标题】:Recount or cache count of mysql tablemysql表的重新计数或缓存计数
【发布时间】:2016-01-05 10:59:00
【问题描述】:

我想在我的网站上显示队列中的提醒数量作为统计数据。该统计数据是我表中的行数。我过去一直在做的是有一个单独的表来缓存数字。缓存表只有一行和一列包含提醒表中的行数。每次添加新提醒时,我都会有另一个查询将值加一。

我最近开始将count() 函数合并到我的项目中。我的问题是;每次有人加载页面时在表上执行count() 操作以显示当前提醒的数量(统计信息显示在页脚中)是更好的性能还是将该数字存储在另一个表中更快所以我只是从那张桌子上看书?在什么时候使用缓存值而不是计数函数会更快?

【问题讨论】:

  • 计数有多大?
  • 只有 2,000 行,所以我意识到这两种方式都没有太大区别。我想知道的是它对大桌子有什么影响。

标签: mysql sql caching


【解决方案1】:

与最优化相关的问题一样,答案是:嗯,这取决于。

如果您的表使用 myisam 表类型,则行数已经缓存在表本身中,并且 count(*) 没有 where 将读取该数字。

如果您使用 innodb 表引擎并且您有大量的插入和较少的选择,那么维护计数将比计数行更昂贵。如果你没有太多的插入,那么使用缓存的数字可能会更快,因为 innodb 在 count(*) 没有 where 时相对较慢。

请参阅mysql performance blog on count(*) 了解有关 innodb 的更多详细说明。

【讨论】:

  • 感谢您对 MyISAM 引擎的评论。这就是我的表使用的,但我不知道它为我缓存了值。我想这回答了我的问题。
【解决方案2】:

如果您正在考虑缓存行计数,您可能不应该也可能不需要它。有一个内置机制

SHOW TABLE STATUS

该查询的部分输出包括:

行数。一些存储引擎,例如 MyISAM,存储 准确计数。对于其他存储引擎,例如 InnoDB,此值为 一个近似值,可能与实际值相差多达 40 到 50%。在这种情况下,请使用 SELECT COUNT(*) 获得准确的 数。

对于 INFORMATION_SCHEMA 数据库中的表,Rows 值为 NULL。

本段还回答了您关于 SELECT COUNT(*) 效率的问题 - 在 MyISAM 表上它很快,它不依赖于表中的行数,因为使用了内部计数器。

innodb 有何不同?

Innodb 不会保留表中的内部行数,因为并发 事务可能同时“看到”不同数量的行。 为了处理 SELECT COUNT(*) FROM t 语句,InnoDB 扫描索引 如果索引不完全在表中,则需要一些时间 缓冲池。如果您的表不经常更改,请使用 MySQL 查询缓存是一个很好的解决方案。要快速计数,您必须使用 您自己创建的计数器表并让您的应用程序更新它 根据插入和删除它。如果一个近似的行 count 足够了,可以使用 SHOW TABLE STATUS。

请注意,这部分文档确实提到了缓存计数。但是您会注意到,如果有一个索引完全覆盖该表,则 count(*) 查询仍然很快。由于您自然有一个主键,并且该主键可能至少部分位于缓冲区中,因此性能影响可以忽略不计。

请注意,在其他流行的开源数据库 Postgresql 中,情况完全不同。有 count(*) 减慢与表大小成比例。值得庆幸的是,在 mysql 中它并没有那么糟糕。

结论:由于缓存行数只是近似值,您可以只使用 show table status 来代替。

【讨论】:

    【解决方案3】:

    您在问使用count 函数是否更好? ,从技术上讲这是更好的方法,但这始终取决于您的数据有多大,如果您正在处理大量数据,则在每次页面加载时调用 count 并不是一个好主意,因为它会影响页面的呈现,在这种情况下,它会使页面加载太慢,如果您计算的是少量数据,那么这是一种更好的方法。

    【讨论】:

    • 在什么时候你会说使用缓存值而不是计数函数会更好?
    • @blazerunner44 ,使用缓存值不需要您计算每次页面加载,因为数据已经存储在缓存中。
    • 是的,我知道每次页面加载时它都不算数。每次页面加载时,它都会从单独的表中读取缓存值。
    • @blazerunner44,很高兴你知道,所以我想你已经知道“在什么时候你会说使用缓存值而不是计数函数会更好?”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 2017-10-26
    相关资源
    最近更新 更多