我应该如何在mysql中查询

时间:2015-04-07 03:02:01

标签: php mysql sql

我有一个网络应用程序,我在其中显示基于此表架构的一系列帖子(有这样的数千行和其他列也被删除(此问题不需要删除)): -

+---------+----------+----------+
|   ID    |   COL1   |   COL2   |
+---------+----------+----------+
|   1     |    NULL  |   ----   |
|   2     |    ---   |   NULL   |
|   3     |    NULL  |   ----   |
|   4     |    ---   |   NULL   |
|   5     |    NULL  |   NULL   |
|   6     |    ---   |   NULL   |
|   7     |    NULL  |   ----   |
|   8     |    ---   |   NULL   |
+---------+----------+----------+

我使用这个查询: -

SELECT * from `TABLE` WHERE `COL1` IS NOT NULL AND `COL2` IS NULL ORDER BY `COL1`;

我得到的结果集如下: -

+---------+----------+----------+
|   ID    |   COL1   |   COL2   |
+---------+----------+----------+
|   12    |    ---   |   NULL   |
|   1     |    ---   |   NULL   |
|   6     |    ---   |   NULL   |
|   8     |    ---   |   NULL   |
|  11     |    ---   |   NULL   |
|  13     |    ---   |   NULL   |
|   5     |    ---   |   NULL   |
|   9     |    ---   |   NULL   |
|   17    |    ---   |   NULL   |
|   21    |    ---   |   NULL   |
|   23    |    ---   |   NULL   |
|   4     |    ---   |   NULL   |
|   32    |    ---   |   NULL   |
|   58    |    ---   |   NULL   |
|   61    |    ---   |   NULL   |
|   43    |    ---   |   NULL   |
+---------+----------+----------+

请注意,由于order by子句,ID列是混乱的。

我有适当的索引来优化这些查询。  现在,让我解释一下真正的问题。我的网络应用程序中有一种延迟加载的功能。因此,在查询第一页后,我使用LIMIT 10显示每页大约10个帖子。

我们在这里很好。但是,当我必须加载第二页时,真正的问题就来了。我现在要查询什么?我不想重复这些帖子。并且几乎每15秒就有一个新帖子出现,这使得它们在结果集中排在最前面(通过顶部我的字面意思是第一行)(我不想在第二或第三页显示这些最新帖子,但它们会改变结果集大小,所以我不能将LIMIT 10,10用于第二页,依此类推,因为帖子将重复。)。

现在,我所知道的是我显示的帖子的最后一个ID。在这里说21。所以,我想显示ID 23,4,32,58,61,43的帖子(请参阅上面的结果集表)。现在,我是否在不使用LIMIT子句的情况下加载所有行,并在ID 21后显示10个ID。但为此,我将不得不对数千个无用的行进行交互。但是,我不能在第2,第3 ......页面上使用LIMIT子句。此外,ID是混乱的,所以我绝对不能使用WHERE ID>...。那么,我们现在去哪里?

4 个答案:

答案 0 :(得分:3)

我不确定我是否正确理解了你的问题,但我想我会怎么做:

  • 在表格中添加时间戳列,我们将其称为date_added
  • 在显示第一页时,按原样使用您的查询(使用LIMIT 10)并挂起最新记录的时间戳;我们称之为last_date_added
  • 对于第二页,第三页及后续页面,请修改您的查询,以使用date_added > last_date_added过滤掉所有记录,并使用LIMIT 10, 10LIMIT 20, 10,{{ 1}}等等。

这样可以及时冻结结果集,并在每次访问第一页时重置它。

备注:

  • 根据结果集的顺序,您可能需要单独的查询来获取LIMIT 30, 10。或者,您可以在当前时间切断,即访问第一页的时间。
  • 如果您的ID是连续的,您可以使用与ID相同的技巧。

答案 1 :(得分:2)

嗯.. 我想了一会儿,想出了两个解决方案。 : -

  1. 存储已显示的帖子的ID并查询WHERE ID NOT IN(id1,id2,...)。但是,这将花费你额外的记忆。如果用户加载100页并且id为100000s,那么单个GET请求将无法处理它。至少在所有浏览器中都没有。可以使用POST请求。

  2. 更改显示COL1的帖子的方式。我不知道这对你来说是不是一个好方法。但是,它可以为您节省带宽并使您的代码更清晰。这也可能是一种更好的方式。我建议这样做: - SELECT * from TABLE where COL1 IS NOT NULL AND COL2 IS NULL AND Id>.. ORDER BY ID DESC LIMIT 10,10。这可能会影响您突显显示帖子的方式。但是,正如您在评论中所说,检查帖子是否符合条件并将COL1从NULL更改为当前时间戳时,我想发布的帖子越新,您想要显示的就越多。这只是一个想法。

答案 2 :(得分:1)

我假设新帖子的ID会比目前的最大ID更高吗?所以你不能只运行你的查询并获取当前的最大ID。然后,当您查询第2页时,执行相同的查询,但使用“ID< max_id”。这应该为您提供与第1页查询相同的结果集,因为任何新行都将具有ID> max_id。希望有帮助吗?

答案 3 :(得分:1)

怎么样?

ORDER BY `COL1`,`ID`;

这将始终按顺序放置ID。这将允许您使用:

LIMIT 10,10

第二页。