我的数据库有大约15万个DocumentNames记录,而我所做的只是与NameTypes的简单连接。 NameTypeID是DocumentNames中的外键。

这是我的查询:

With cte as
(
    Select ROW_NUMBER() OVER
    (Order By nm.Name asc )
    peta_rn,
    dn.DocumentNameID,
    dn.DocumentID
    From DocumentNames dn

    Left Join NameTypes nm On dn.NameTypeID = nm.NameTypeID
)
Select * from cte Where peta_rn >= 10000 And peta_rn <= 10050

这是屏幕截图:

排序花费90%的费用。我现在很困惑该怎么办。我想敲我的头,但我不能,因为周围有人。请建议我该怎么办?

最佳答案

对于它的价值,这里是some SQLFiddle来测试任何语法。

到目前为止,最简单的方法是避免按NameTypes顺序插入Name,因此,按字母顺序分配NameTypeID

在这种情况下,无需加入NameTypes表。你可以做的

WITH [CTE] AS
(
SELECT
            ROW_NUMBER() OVER (ORDER BY [NameTypeID] ASC) [PetaRN],
            [DocumentNameID],
            [DocumentID]
    FROM
            [DocumentNames]
)
SELECT
            [PetaRN],
            [DocumentNameID],
            [DocumentID]
    FROM
            [CTE]
    WHERE
            [PetaRN] BETWEEN 10000 AND 10050
    ORDER BY
            [PetaRN] ASC;

怎么样
WITH [CTE] AS
(
SELECT
            ROW_NUMBER() OVER (ORDER BY [NameTypeID] ASC) [PetaRN],
            [DocumentNameID],
            [DocumentID]
    FROM
            [DocumentNames]
)
SELECT TOP 50
            [PetaRN],
            [DocumentNameID],
            [DocumentID]
    FROM
            [CTE]
    WHERE
            [PetaRN] >= 10000
    ORDER BY
            [PetaRN] ASC;

在SQL 2005上测试大型数据集时,我注意到CTE在大型结果集上的表现不佳,这可能与服务器上的资源可用性有关。临时表的反直观使用可能会更快。这还允许您索引行号,从而可以快速选择页面,但是,这必须抵消插入成本。试试看。
CREATE TABLE #Peta
(
    [PetaRN] BigInt NOT NULL CONSTRAINT [PK_Peta] PRIMARY KEY CLUSTERED,
    [DocumentNameID] Int NOT NULL,
    [DocumentID] Int NOT NULL
);

INSERT #Peta
SELECT
            ROW_NUMBER() OVER (ORDER BY [NameTypeID] ASC) [PetaRN],
            [DocumentNameID],
            [DocumentID]
    FROM
            [DocumentNames];

SELECT TOP 50
            [PetaRN],
            [DocumentNameID],
            [DocumentID]
    FROM
            #Peta
    WHERE
            [PetaRN] >= 10000
    ORDER BY
            [PetaRN] ASC;


DROP TABLE #Peta;

08-16 06:17