Php Mysql在高流量数据库上使用过滤器统计行数

Php Mysql在高流量数据库上使用过滤器统计行数,php,mysql,algorithm,count,Php,Mysql,Algorithm,Count,假设您有一个具有多个选择字段的搜索表单,假设用户从下拉列表中选择一个选项,但在提交数据之前,我需要显示数据库中的行数 假设该网站每天至少有30万(30万)访问者,用户从表单中选择选项的次数至少为40次,这意味着1200万ajax请求+1200万数据库查询,这似乎有点太多了 问题是如何实现快速计数(使用php(Zend Framework)和MySQL),以便数据库上额外的1200万个查询不会影响站点的负载 一种解决方案是使用一个表来存储选择字段的所有组合及其各自的计数(在产品表中添加或删除产品时

假设您有一个具有多个选择字段的搜索表单,假设用户从下拉列表中选择一个选项,但在提交数据之前,我需要显示数据库中的行数

假设该网站每天至少有30万(30万)访问者,用户从表单中选择选项的次数至少为40次,这意味着1200万ajax请求+1200万数据库查询,这似乎有点太多了

问题是如何实现快速计数(使用php(Zend Framework)和MySQL),以便数据库上额外的1200万个查询不会影响站点的负载

一种解决方案是使用一个表来存储选择字段的所有组合及其各自的计数(在产品表中添加或删除产品时,存储计数的表将被更新)。虽然这不是一个好主意,但对于43个过滤器中的8个过滤器(选择选项),将插入需要管理的+8M行

关于如何实现这一点,还有其他想法吗


p、 我不需要代码示例,只需要在这种情况下工作的想法本身。

我可能会有一个预先计算过的表——正如您建议的那样。重要的是,您有一个智能机制来实现两件事:

  • 轻松查询哪些条目受哪些更改影响
  • 为整个表单请求提供唯一的查找字段
  • 如果您有实数键,那么8M项就没有多大意义,因为您只需要直接查找

    我会不厌其烦地在所有必要的地方为这个表编写具体的更新。即使有大量的更改,这仍然是有效的。如果操作正确,您将知道在插入/更新/删除产品时需要更新或使哪些行无效

    旁注
    根据你的评论。如果您需要在八个位置添加代码以覆盖所有位置,则可以删除—这可能是重构和集中一些代码的好时机。

    很少有场景

  • mysql有查询缓存,如果表的更新不是那么频繁的话,你不必麻烦缓存

  • 99%
    用户不必担心匹配的结果有多少,
    他/她只需要前几条记录

  • 使用
    explain
    -如果您注意到
    explain
    将返回查询中要匹配的行数,
    不是100%精确的
    ,但应足以用作粗略的行数


  • 您可以轻松优化以下几点:

  • 缓存您可以缓存的所有内容。例如,下拉列表的选项是否需要通过ajax调用获取?在实现memcache时回答了我的许多问题,当然memcached.org也有很好的文档可用

  • 提供任何可以静态提供的服务。例如,不经常更改的选项可以每小时通过cron以数组形式存储在平面文件中,并在运行时包含在脚本中

  • 对于任何严重的应用程序负载,具有默认配置设置的MySQL通常是次优的,应该调整以满足手头任务的需要。也许可以寻找高性能的读访问

  • 你可以看看,事实上,整个博客确实是mysql性能技巧的金矿


    祝你好运

    这并不是你想要的,但是因为你有很多选择,并且想根据这些选择来计算可用的项目,你应该看看Lucene及其分面搜索。它是用来解决这样的问题的


    如果您不需要从搜索中获取最新信息,您可以使用队列系统不时向Lucene推送更新和插入(这样您就不必每天为Lucene推送数千次更新和插入而烦恼)。

    您实际上只有三个选项,再多的搜索也不可能发现第四个:

  • 手动计算结果。O(n)表示查询时的结果总数
  • 存储并维护每个过滤器组合的计数。O(1)检索计数,但需要O(2^n)存储和O(2^n)时间在记录更改时更新所有计数
  • 缓存计数,仅在缓存中找不到时计算它们(每1个)。O(1)当数据在缓存中时,O(n)否则
  • 正是因为这个原因,那些必须超越琐碎的系统——也就是说,大多数系统——要么限制它们将统计的结果数量(例如,GMail收件箱中的项目或谷歌阅读器中未读的项目),要么根据统计数据(例如,谷歌搜索结果计数)估计计数,要么两者兼而有之


    我想您可能需要准确的用户数量,没有限制,但很难想象实际需要这样做的场景。

    大概您是在使用ajax对您所说的后端进行调用。使用某种类型的切面平面文件作为数据的中间文件。将过期时间设置为5秒或任何合适的时间。将数据文件命名为查询键=值字符串。在ajax请求中,如果数据文件早于您的冷却时间,则刷新,如果不是,则使用存储在数据文件中的值


    此外,您可能低估了mysql查询缓存机制的强度。如果您使用的是mysql查询缓存,我怀疑与我刚才描述的方式相比,性能会有任何明显的下降。如果查询是由mysql缓存的,那么实际上唯一的减速效果将来自应用程序和mysql之间的网络层。

    考虑复制在您的体系结构中可以扮演什么角色。如果需要扩展,可以考虑将表从NoNDB复制到MyISAM。如果您执行alter table A add index ixA (a, b); select count(a) using from A use index(ixA) where a=1 and b=2;
    CREATE TABLE counts (
      id unsigned integer auto_increment primary key
      option integer indexed using hash key
      user_id integer indexed using hash key
      rowcount unsigned integer
      unique key user_option (user, option)
    ) engine = memory
    
    DELIMITER $$
    
    CREATE TRIGGER ai_tablex_each AFTER UPDATE ON tablex FOR EACH ROW
    BEGIN
      IF (old.option <> new.option) OR (old.user_id <> new.user_id) THEN BEGIN
        UPDATE counts c SET c.rowcount = c.rowcount - 1 
          WHERE c.user_id = old.user_id and c.option = old.option; 
        INSERT INTO counts rowcount, user_id, option  
          VALUES (1, new.user_id, new.option)
          ON DUPLICATE KEY SET c.rowcount = c.rowcount + 1; 
      END; END IF;
    END $$
    
    DELIMITER ;