簡體   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