我的数据库有大约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;