Php Mysql在高流量数据库上使用过滤器统计行数
假设您有一个具有多个选择字段的搜索表单,假设用户从下拉列表中选择一个选项,但在提交数据之前,我需要显示数据库中的行数 假设该网站每天至少有30万(30万)访问者,用户从表单中选择选项的次数至少为40次,这意味着1200万ajax请求+1200万数据库查询,这似乎有点太多了 问题是如何实现快速计数(使用php(Zend Framework)和MySQL),以便数据库上额外的1200万个查询不会影响站点的负载 一种解决方案是使用一个表来存储选择字段的所有组合及其各自的计数(在产品表中添加或删除产品时,存储计数的表将被更新)。虽然这不是一个好主意,但对于43个过滤器中的8个过滤器(选择选项),将插入需要管理的+8M行 关于如何实现这一点,还有其他想法吗Php Mysql在高流量数据库上使用过滤器统计行数,php,mysql,algorithm,count,Php,Mysql,Algorithm,Count,假设您有一个具有多个选择字段的搜索表单,假设用户从下拉列表中选择一个选项,但在提交数据之前,我需要显示数据库中的行数 假设该网站每天至少有30万(30万)访问者,用户从表单中选择选项的次数至少为40次,这意味着1200万ajax请求+1200万数据库查询,这似乎有点太多了 问题是如何实现快速计数(使用php(Zend Framework)和MySQL),以便数据库上额外的1200万个查询不会影响站点的负载 一种解决方案是使用一个表来存储选择字段的所有组合及其各自的计数(在产品表中添加或删除产品时
p、 我不需要代码示例,只需要在这种情况下工作的想法本身。我可能会有一个预先计算过的表——正如您建议的那样。重要的是,您有一个智能机制来实现两件事:
根据你的评论。如果您需要在八个位置添加代码以覆盖所有位置,则可以删除—这可能是重构和集中一些代码的好时机。很少有场景
99%
用户不必担心匹配的结果有多少,他/她只需要前几条记录
explain
-如果您注意到explain
将返回查询中要匹配的行数,不是100%精确的
,但应足以用作粗略的行数您可以轻松优化以下几点:
祝你好运这并不是你想要的,但是因为你有很多选择,并且想根据这些选择来计算可用的项目,你应该看看Lucene及其分面搜索。它是用来解决这样的问题的
如果您不需要从搜索中获取最新信息,您可以使用队列系统不时向Lucene推送更新和插入(这样您就不必每天为Lucene推送数千次更新和插入而烦恼)。您实际上只有三个选项,再多的搜索也不可能发现第四个:
我想您可能需要准确的用户数量,没有限制,但很难想象实际需要这样做的场景。大概您是在使用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 ;