- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在使用 SQL Server 进行分页,我想通过计算结果总数作为我的部分结果集的一部分来避免重复,而不是获取该结果集然后执行单独的查询以获取计数。然而,麻烦的是,它似乎增加了执行时间。例如,如果我使用 SET STATISTICS TIME ON
检查,则:
WITH PagedResults AS (
SELECT
ROW_NUMBER() OVER (ORDER BY AggregateId ASC) AS RowNumber,
COUNT(PK_MatrixItemId) OVER() AS TotalRowCount,
*
FROM [MyTable] myTbl WITH(NOLOCK)
)
SELECT * FROM PagedResults
WHERE RowNumber BETWEEN 3 AND 4810
...或这个(其执行计划相同):
SELECT * FROM (
SELECT TOP (4813)
ROW_NUMBER() OVER (ORDER BY AggregateId ASC) AS RowNumber,
COUNT(PK_MatrixItemId) OVER() AS TotalRowCount,
*
FROM [MyTable] myTbl WITH(NOLOCK)
) PagedResults
WHERE PagedResults.RowNumber BETWEEN 3 AND 4810
... 平均 CPU 时间(所有查询加起来)似乎是这个的 1.5 到 2 倍:
SELECT * FROM (
SELECT TOP (4813)
ROW_NUMBER() OVER (ORDER BY AggregateId ASC) AS RowNumber,
*
FROM [MyTable] myTbl WITH(NOLOCK)
) PagedResults
WHERE PagedResults.RowNumber BETWEEN 3 AND 4810
SELECT COUNT(*) FROM [MyTable] myTbl WITH(NOLOCK)
显然我宁愿使用前者而不是后者,因为后者冗余地重复了 FROM
子句(如果有的话,我会重复任何 WHERE
子句),但是它的执行时间要好得多,我真的必须使用它。有什么办法可以完全缩短前者的执行时间吗?
最佳答案
CTE 内联到查询计划中。它们的性能与派生表完全相同。
派生表不对应物理操作。他们不会将结果集“具体化”到临时表中。 (我相信 MySQL 可以做到这一点,但 MySQL 是目前最原始的主流 RDBMS。)
使用 OVER()
确实在查询计划中表现为对临时表的缓冲。完全不清楚为什么这会比重新读取基础表更快。缓冲相当慢,因为在 SQL Server 中写入比读取占用更多 CPU。我们可以从原始表中读取两次。这可能就是后一种选择更快的原因。
如果您想避免重复查询的某些部分,请使用 View 或表值函数。诚然,这些都不是一次性查询的好选择。也可以在应用层生成SQL,重复使用字符串。 ORM 也使这变得容易得多。
关于sql - 在 CTE 内部使用 COUNT() 比在 CTE 外部使用更昂贵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26401278/
我正在阅读 MongoDB,并试图了解它的最佳用途。我没有看到明确答案的一个问题是哪些操作便宜或昂贵,以及在什么条件下。 你能帮忙澄清一下吗? 谢谢。 最佳答案 人们经常声称 mongodb 的写入速
我正在寻找一个主要来源(或一个非常好的解释)来支持在为 iPhone 编写软件时使用 autorelease 是危险的或过于昂贵的说法。 许多开发者都提出了这种说法,我什至听说 Apple 不推荐它,
我意识到这离微优化领域太远了,但我很想知道为什么调用 DateTime.Now 和 DateTime.UtcNow 如此“昂贵”。我有一个示例程序,它运行几个场景来做一些“工作”(添加到一个计数器)并
我是一名优秀的程序员,十分优秀!