php - 在 php 和 mysql 大表中更改数据的分页?

标签 php mysql performance pagination

我需要在PHP和Mysql中处理分页,问题陈述如下:
我有一个表,其中包含 2 个外键关系的数十万条记录,例如“用户”和“项目”,并且该表经常更改,为特定用户添加或删除项目。现在我想向用户列出所有项目,并在标题中显示分页和总数。我的表是 MyISAM 并且也使用 SQL_CALC_FOUND_ROWS。表结构如下,基数很大。

CREATE TABLE `USER_ITEMS` (
  `ID` int(11) NOT NULL,
  `ITEMS` int(11) unsigned NOT NULL DEFAULT '0',
  `USER` int(11) unsigned NOT NULL DEFAULT '0',
  `TYPE` char(1) NOT NULL DEFAULT '',
  `TIME` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `SEEN` char(1) NOT NULL,
  `FILTERED` char(1) NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `IND1` (`USER`,`ITEMS`),
  KEY `USER` (`USER`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

我试过的解决方案:

  1. 我对所有分页使用限制在 Mysql 上执行选择,但是如果实时删除,我们会得到重复的项目,或者如果在分页时添加任何项目,我们会得到丢失的项目。而且很多时候,由于排序方式和其他原因,查询速度非常慢条件领先的业绩受到打击。这是带有 where、order by 和 limit 的简单 Select 查询。
  2. 我使用 Memcache 存储他查看过的页面的项目,并在分页期间获取不包括 Memcache 中的项目的项目,但这也会导致查询速度变慢。这是 Select query with where with ITEMS NOT IN , order by and limit .

问题主要是数据的准确性、查询执行时间和网络阻塞方面的性能、php 内存耗尽。

我想知道这些是否是相同的一般做法,或者我们是否有针对此类场景的更好的实现/引擎/缓存。

最佳答案

为了不丢失/重复条目的分页,您需要“记住您离开的地方”而不是使用 OFFSET

也就是对于“下一个”页面,做

WHERE id > $last
ORDER BY id
LIMIT 10

然后保留 [下一步] 按钮的最后一个 ID。 (由于您没有提供您的代码,我不能更具体。)

更多详情见my pagination blog .

INDEX(user) 是多余的,因为您有 UNIQUE(user, items)

考虑删除 id,因为唯一 key 可以提升为 PK。要遍历复合键,请参阅 another blog .

关于php - 在 php 和 mysql 大表中更改数据的分页?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35479889/

相关文章:

mysql - 如何指定在 MySql 中有空格的列名(在 where 子句中)

algorithm - Big O,你如何计算/近似?

php - 从没有标题的流中创建图像?

php - 在 php 上显示 utf8_general_ci 数据(非英语)

mysql - 如何提高mysql中的select性能?

asp.net - 为什么在 Web 应用程序中由 Reporting Services 2005 调用时,第二个 T-SQL 查询的运行速度比第一个快得多

performance - 加速将人 reshape 为 R 中的周期格式数据帧

php - mysql查询只返回一行

javascript - 使用javascript打印本地文件

javascript - 我的 jQuery 脚本似乎正在加载,但不工作