繁体   English   中英

存储SQL Server查询分页的结果

[英]Store results of SQL Server query for pagination

在我的数据库中,我有一个包含相当大数据集的表,用户可以在其上执行搜索。 因此,对于包含大约250,000条记录的Person表的以下表结构:

firstName|lastName|age
---------|--------|---
John     | Doe    |25
---------|--------|---
John     | Sams   |15
---------|--------|---

用户将能够执行可返回约500个左右结果的查询。 我想做的是允许用户使用分页一次查看他的搜索结果50。 我已经找到了客户端分页的东西,但我需要在某处存储查询结果,以便分页使用来自其唯一查询的结果而不是SELECT *语句。

谁能提供一些指导,以达到这个目标的最佳方法? 谢谢。

旁注:我一直在尝试使用临时表通过使用SELECT INTO语句来执行此操作,但我认为这可能会导致一些问题,例如,用户A执行搜索并且他的结果存储在临时表中然后用户B不久后执行搜索,并覆盖用户A的搜索结果。

在SQL Server中, ROW_NUMBER()函数非常适合分页,并且可能会有所帮助,具体取决于搜索之间的参数变化,例如,如果搜索只是针对您可以使用的不同firstName值:

;WITH search AS (SELECT *,ROW_NUMBER() OVER (PARTITION BY firstName ORDER BY lastName) AS RN_firstName
                 FROM YourTable)
SELECT *
FROM search 
WHERE RN BETWEEN 51 AND 100
  AND firstName = 'John'

您可以添加其他ROW_NUMBER()行,根据要搜索的字段更改PARTITION BY子句。

首先,确保你真的需要这样做。 你增加了很大的复杂性,所以去测量一下查询和分页是否真的很痛,或者你只是“觉得你应该”。 可以很容易地使用ROW_NUMBER()处理分页。

假设你继续,一旦你得到了你的查询,显然你需要建立一个缓存,所以首先你需要确定密钥是什么。 它将是SQL语句或操作标识符(可能是存储过程的名称)和使用的标准。 如果您不想在用户之间共享,那么也可以使用用户名或某种会话ID。

现在,当您进行查询时,首先要在此表中查找所有关键数据

a)无法找到它,因此您运行查询并添加到缓存,存储条件/键和数据的数据或PK,具体取决于您是想要快照还是实时。 请记住,“实时”并不是因为其他用户可能正在更改您下面的数据。

b)找到它,因此删除结果(或将PK加入基础表)并返回结果。

当然,现在你需要一个后台进程来清理缓存,因为缓存太长时间了。

就像我说的那样 - 你应该在开始之前确保你需要这样做。 在你给出的例子中,我认为这不值得。

从历史上看,对我们来说,管理它的最佳方法是创建一个具有唯一名称的完整新表。 然后,当您完成后,您可以安排表删除。

如果可行,该表只包含一个索引id(一个简单的序列:1,2,3,4,5)和作为查询一部分的表的主键。 不是整个结果集。

您的分页逻辑会执行以下操作:

SELECT p.* FROM temp_1234 t, primary_table p 
WHERE t.pkey = p.primary_key 
  AND t.serial_id between 51 and 100

序列号是您的分页索引。

所以,你最终得到的东西(注意,我不是SQL Server的人,所以请原谅):

CREATE TABLE temp_1234 (
    serial_id serial,
    pkey number
);

INSERT INTO temp_1234
  SELECT 0, primary_key FROM primary_table WHERE <criteria> ORDER BY <sort>;

CREATE INDEX i_temp_1234 ON temp_1234(serial_id); // I think sql already does this for you

如果你可以推迟索引,它比首先创建它更快,但它最有可能是一个微小的改进。

此外,创建一个跟踪表,您可以在其中插入表名和日期。 你可以在晚些时候(深夜)使用收割机进程来DROP日期表(比那些X小时更多)。

全表操作比插入和删除单个表中的行要便宜得多:

INSERT INTO page_table SELECT 'temp_1234', <sequence>, primary_key...

DELETE FROM page_table WHERE page_id = 'temp_1234';

那太糟糕了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM