我有两个不同的查询,每页返回10条记录。但是在我的第二个查询中,我已经更新了它以返回总记录数,并且已经使用CTE实现了。现在我不愿意使用它,并想知道性能影响,因为现在它在Query 02
中使用了CTE。 CTE会选择内存中表的所有记录并使其占用大量内存吗?这两个查询之间的性能差异有多大?因为如果存在巨大的性能差异,那么我可以跳过总计数。请建议。
DECLARE
@PageSize tinyint=10,
@PageOffset int=0;
--Query 01
SELECT
App.Id,
Users.FirstName+' '+Users.LastName as Name,
App.Date
FROM
App
INNER JOIN Users ON App.UserId = Users.Id
WHERE
App.FolderId = 1
ORDER BY
App.Date DESC
OFFSET @PageOffset ROWS FETCH NEXT @PageSize ROWS ONLY;
--Query 02
WITH TempResult AS(
SELECT
App.Id,
Users.FirstName+' '+Users.LastName as Name,
App.Date
FROM
App
INNER JOIN Users ON App.UserId = Users.Id
WHERE
App.FolderId = 1
), TempCount AS (
SELECT COUNT(*) AS MaxRows FROM TempResult
)
SELECT *
FROM TempResult, TempCount
ORDER BY
TempResult.Date DESC
OFFSET @PageOffset ROWS FETCH NEXT @PageSize ROWS ONLY;
答案 0 :(得分:0)
CTE-s以及视图都是优化边界。即查询计划无法与外部查询一起优化WITH
查询。在你的情况下,它不是一个问题,因为外部查询很简单。它是两个表中的Cartesian Product个。
通常不鼓励笛卡尔积。但是,其中一个视图只包含一行。所以应该没问题。
答案 1 :(得分:0)
我不明白你为什么要使用多个子查询。编写查询的最佳方法是使用窗口函数:
for tmpfile in /home/asmita/tmp
do
mv "$tmpfile" "C_${tmpfile}"
mv "C_${tmpfile}" /home/tgasmita
done
至于性能,这取决于您是否正在测量第一行行或最后一行行的时间。您的初始查询可以在生成结果时开始返回结果,因为没有SELECT a.Id, (u.FirstName + ' '+ u.LastName) as Name, a.Date,
COUNT(*) OVER () as MaxRows
FROM App a INNER JOIN
Users u
ON a.UserId = u.Id
WHERE a.FolderId = 1;
或ORDER BY
或窗口函数。这与CTE的存在无关。
任何具有总计数的版本都需要生成整个结果集。这需要在返回任何内容之前在内部生成所有结果。
您应该测试以查看查询是否符合您的性能需求。
答案 2 :(得分:0)
由于你要进行分页并找到两个总记录,我使用窗口函数。
它使用单行号功能帮助我。
请更正查询的其余部分。喜欢计算@From和@To。纠正row_number()部分,以满足您的需要。还要注意通知部分并使用更快的部分。
DECLARE @PageSize tinyint=10,
@PageOffset int=0;
--Query 01
;with CTE as
(
SELECT
App.Id,
Users.FirstName+' '+Users.LastName as Name,
App.Date ,ROW_NUMBER()over(order by date desc) rn
FROM
App
INNER JOIN Users ON App.UserId = Users.Id
WHERE
App.FolderId = 1
)
select *
,(select max(rn) from cte) TotalRecords
--,(select top 1 rn from cte order by rn desc) TotalRecords
from cte
where rn between @From and @To