10

SQLServer 2000でページングクエリを実行する最も効率的な方法は何でしょうか?

「ページングクエリ」は、MySQLでLIMITステートメントを使用するのと同じです。

編集:その場合、ストアドプロシージャは、セットベースのクエリよりも効率的でしょうか?

4

5 に答える 5

12

大規模な結果セットのページングと勝者はRowCountを使用しています。また、より複雑なクエリ用の一般化されたバージョンもあります。しかし、ジャスミン・ムハレモビッチの功績を認めてください:)

DECLARE @Sort /* the type of the sorting column */
SET ROWCOUNT @StartRow
SELECT @Sort = SortColumn FROM Table ORDER BY SortColumn
SET ROWCOUNT @PageSize
SELECT ... FROM Table WHERE SortColumn >= @Sort ORDER BY SortColumn

この記事には、ソースコード全体が含まれています。

「アップデート2004-05-05」情報をお読みください。!

于 2009-02-06T16:05:51.593 に答える
6

SELECT TOP nネストされたクエリは、おそらくそれを達成するための最も効率的な方法だと思います。

SELECT TOP ThisPageRecordCount *
FROM Table
WHERE ID NOT IN (SELECT TOP BeforeThisPageRecordCount ID FROM Table ORDER BY OrderingColumn)
ORDER BY OrderingColumn

ThisPageRecordCount1 ページあたりの項目数とBeforeThisPageRecordCountに置き換えます(PageNumber - 1) * items-per-page

もちろん、SQL Server 2005 でより良い方法はROW_NUMBER()、CTE で関数を使用することです。

于 2009-02-02T15:25:55.827 に答える
1

クエリの効率は、基になるテーブルの構造に大きく依存します。たとえば、IDENTITY である ID という主キーがあり、それがクラスター化インデックスであり、誰も IDENTITY_INSERT を実行していないと想定できる場合、次のようなクエリを実行できます。

SELECT TOP XXX FROM table WHERE ID > @LastPagesID;

そうすれば最速で結果が得られます。本当に効率的である他のすべてのものは、これのいくつかの変形です.IDではないかもしれません.ページに使用しているのは、実際には一意であることがわかっている日付ですが、要点はわかります.ここに示す IN () ベースのクエリはおそらく機能しますが、部分的なクラスター化またはカバー インデックス スキャンのパフォーマンスには影響しません。

于 2009-02-07T03:29:17.673 に答える
0

これは、任意のテーブルでページネーションを実行する一般的な SQL Server 2000 ストアド プロシージャです。ストアド プロシージャは、テーブルの名前、出力する列 (既定ではテーブル内のすべての列)、オプションの WHERE 条件、オプションの並べ替え順序、取得するページ番号、およびページあたりの行数を受け入れます。

    CREATE PROCEDURE [dbo].[GetPage]
    @pTableName VARCHAR(30),
    @pColumns VARCHAR(200) = '*',
    @pFilter VARCHAR(200) = '',
    @pSort VARCHAR(200) = '',
    @pPage INT = 1,
    @pPageRows INT = 10
    AS

    SET NOCOUNT ON
    DECLARE @vSQL VARCHAR(4000)
    DECLARE @vTempTable VARCHAR(30)
    DECLARE @vRowStart INT
    DECLARE @vTotalRows INT

    SET @vTempTable = '##Tmp' + CAST(DATEPART(YYYY, GETDATE()) AS VARCHAR(4)) +
    CAST(DATEPART(MM, GETDATE()) AS VARCHAR(2)) +
    CAST(DATEPART(DD, GETDATE()) AS VARCHAR(2)) +
    CAST(DATEPART(HH, GETDATE()) AS VARCHAR(2)) +
    CAST(DATEPART(MI, GETDATE()) AS VARCHAR(2)) +
    CAST(DATEPART(SS, GETDATE()) AS VARCHAR(2)) +
    CAST(DATEPART(MS, GETDATE()) AS VARCHAR(3))

    SET @vSQL = 'SELECT ' + @pColumns + ', IDENTITY(INT, 1, 1) AS ROWID INTO ' + @vTempTable + ' FROM ' + @pTableName

    IF @pFilter != '' AND @pFilter IS NOT NULL
    SET @vSQL = @vSQL + ' WHERE ' + @pFilter

    IF @pSort != '' AND @pSort IS NOT NULL
    SET @vSQL = @vSQL + ' ORDER BY ' + @pSort

    EXECUTE (@vSQL)

    -- Get the total number of rows selected
    SET @vTotalRows = @@ROWCOUNT

    -- If page number = 0, set it to the first page
    IF @pPage = 0
    SET @pPage = 1

    -- If page number is beyond the last page, set page to the last page
    IF (@pPage * @pPageRows) > @vTotalRows
    BEGIN
    SET @pPage = @vTotalRows / @pPageRows
    IF (@vTotalRows % @pPageRows) != 0
    SET @pPage = @pPage + 1
    END

    SET @vRowStart = ((@pPage - 1) * @pPageRows) + 1
    SET @vSQL = 'SELECT * FROM ' + @vTempTable + ' WHERE ROWID BETWEEN ' + CAST(@vRowStart AS VARCHAR(10)) +
    ' AND ' + CAST((@vRowStart + @pPageRows - 1) AS VARCHAR(10)) + ' ORDER BY ROWID'
    EXECUTE (@vSQL)

    SET @vSQL = 'DROP TABLE ' + @vTempTable
    EXECUTE (@vSQL)

GO

Northwing データベースを使用した使用方法の例を次に示します。

EXECUTE [dbo].[GetPage] 'Customers', '*', '', '', 1, 10
EXECUTE [dbo].[GetPage] 'Customers', '*', '', 'CustomerID DESC', 1, 10

確認のため、これは私の作品ではありませんが、 http://www.eggheadcafe.com/PrintSearchContent.asp? LINKID=1055 の好意によるものです

乾杯、ジョン

于 2009-02-09T12:49:44.857 に答える
0

ここにあるものは、SQL 2005 にアップグレードする説得力のある理由だと思います。

SQL 2005 では、これは次の方法ですばやく簡単に実行できます。

select ROW_NUMBER() over (order by [MyField]) as rowNum, *
from [MyTable]
where rowNum between @firstRow and @lastRow

あなたが本当に SQL 2000 に行き詰まっているなら、私は心配します.2 世代前の今では Microsoft は SQL 2000 を完全にサポートするつもりはありません.

残念ながら、これを行う最善の方法は 1 つではありません。すべての解決策はちょっとしたハックです。

ただし、@Petar Petrovの答えはおそらく最も一貫しています。

  • 小さいテーブルでクラスター化されたインデックスを並べ替えに使用している場合は、ASC-DESC メソッド (TOP を使用してそれぞれの方法で 2 つの並べ替えを動的に構築する) の方がおそらく高速です。
  • データが比較的静的で、並べ替えが固定されている場合は、並べ替え順序を変更したときに更新する独自の rowNum フィールドを追加できます (ひどいように聞こえますが、大きなテーブルでは高速になります)。

毎回、クエリ アナライザーで微調整するのに数時間かかっていると思います。ストアド プロシージャはどちらの方法でも大きな違いはありません。クエリ プランのキャッシュがボトルネックになる可能性は低いです。

于 2009-02-09T08:57:29.113 に答える