我需要知道查询返回的总行数,以填充网页中的分页文本。
我在SQL端进行分页以提高性能。
使用下面的查询,我在 15秒中获得了6560条记录,这对我的需求很慢:
1
SELECT COUNT(*)
FROM dbo.vw_Lista_Pedidos_Backoffice_ix vlpo WITH (NOLOCK)
WHERE dataCriacaoPedido>=DATEADD(month,-6,getdate())
使用此查询,我在 1秒:
中得到相同的结果2
SELECT COUNT(*) FROM
(SELECT *, ROW_NUMBER() over (order by pedidoid desc) as RowNumber
FROM dbo.vw_Lista_Pedidos_Backoffice_ix vlpo WITH (NOLOCK)
WHERE
dataCriacaoPedido>=DATEADD(month,-6,getdate())
) records
WHERE RowNumber BETWEEN 1 AND 6560
如果我更改上面的查询(2.)并将RowNumber的上限设置为大于6560的数字(计数结果(*)),则查询再次 15秒运行!
所以,我的问题是: - 为什么查询2.花费的时间更少,即使RowNumber的限制实际上不限制子查询中的任何行? - 有什么方法可以使用查询2.我有利于获得总行数吗?
所有人:)
答案 0 :(得分:0)
这并不能完全回答你的问题,因为真正的答案在于视图定义和优化。这是为了回答有关行为的问题。
COUNT(*)
较慢的原因是因为它必须生成视图中的所有行,然后对它们进行计数。计算不是问题。这一代是。
ROW_NUMBER() over (order by pedidoid desc)
速度快的原因是因为pedidoid
上存在索引。 SQL Server使用ROW_NUMBER()
的索引。同样重要的是,它可以使用相同的索引访问视图中的数据。因此,这加快了查询速度。
为什么有一个幻数为6,561的原因。好吧,我不知道。这与SQL Server优化器和配置的变幻莫测有关。一种可能性与WHERE
子句有关:
WHERE dataCriacaoPedido >= DATEADD(month, -6, getdate())
我的猜测是该条件有6,560个匹配。但是,SQL Server必须扫描整个表。它扫描表格,找到匹配的值。但是,引擎不知道它已完成,因此它不断搜索行。正如我所说,这是解释行为的猜测。
确实修复了查询,您需要了解视图的工作原理。