简体   繁体   English

使用顶部和计数的最佳方法 - SQL 服务器 2008

[英]Best Approach to using Top and Count - SQL Server 2008

I have an 2008 C# application (back end SQL Server 2008) where sometimes queries return a large number of results.我有一个 2008 C# 应用程序(后端 SQL Server 2008),有时查询会返回大量结果。 So, I researched some paging algorithms and put one in place that uses the TOP statement.所以,我研究了一些分页算法,并使用了 TOP 语句。 I love the fact that if I have 500 total results and am only showing 20 results per page that I can only query the database for 20 records instead of storing all 500 records in memory.我喜欢这样一个事实,即如果我有 500 个总结果并且每页只显示 20 个结果,那么我只能在数据库中查询 20 条记录,而不是将所有 500 条记录存储在 memory 中。

The issue I have though is that in order to implement the paging algorithm, I need to know how many total records there are in this query.我遇到的问题是,为了实现分页算法,我需要知道这个查询中有多少条记录。 So, what I have done is to just run another query with the same parameters that just selects the ID (instead of the whole object) to try to make it run quickly.所以,我所做的只是运行另一个具有相同参数的查询,只选择 ID(而不是整个对象)以尝试使其快速运行。 For some reason though, I think that running these two queries (thus establishing 2 connections) isn't the best approach.但出于某种原因,我认为运行这两个查询(从而建立 2 个连接)并不是最好的方法。

So I need the count of all of the records but only want to select the limited number used in TOP.所以我需要所有记录的计数,但只想 select TOP 中使用的有限数量。 Would a temporary table be of use here?临时表在这里有用吗? I have two different stored procedures now.我现在有两个不同的存储过程。

Thanks for any "best practices" advice anyone can give.感谢任何人都可以提供的任何“最佳实践”建议。

You could use object datasource...to implement this custom paging.您可以使用 object 数据源...来实现此自定义分页。

I would use ROW_NUMBER() OVER (ORDER BY...) .我会使用ROW_NUMBER() OVER (ORDER BY...) More details here .更多细节在这里

I don't know what approach that you are taking for paging however the technique that I usually use is to use the ROW_NUMBER function, for example:我不知道您采用什么方法进行分页但是我通常使用的技术是使用ROW_NUMBER function,例如:

SELECT  Description, Date
FROM
(
    SELECT  ROW_NUMBER() OVER (ORDER BY Date DESC) AS Row,
        Description, Date 
    FROM Log
) AS LogWithRowNumbers
WHERE  Row >= 1 AND Row <= 10

This approach is the cleanest that I am aware of, works with any subquery and only requires a single query.这种方法是我所知道的最干净的方法,适用于任何子查询,并且只需要一个查询。

Of course if you wish to show a "total hits" or similar on your page then you will also need another query to get the row count:当然,如果您希望在页面上显示“总点击数”或类似信息,那么您还需要另一个查询来获取行数:

SELECT COUNT(*) FROM Log

However you can execute both statements in the same batch to prevent the need for an extra "round trip" to the databse server.但是,您可以在同一批次中执行这两个语句,以防止需要额外的“往返”到数据库服务器。

Source - Paging Records Using SQL Server 2005 Database - ROW_NUMBER Function来源 -使用 SQL 服务器 2005 数据库的分页记录 - ROW_NUMBER Function

If you perform both selects within your stored proceedure you would get two datatables in your dataset after using the Fill method.如果您在存储过程中执行两个选择,则在使用 Fill 方法后,您将在数据集中获得两个数据表。

I would try something like this:我会尝试这样的事情:

;WITH CTE AS
(
    SELECT 
        ROW_NUMBER() OVER (ORDER BY Date DESC) AS Row,
        COUNT(*) OVER() AS TotalCount,
        Description, Date 
    FROM Log
)

SELECT *
FROM CTE
WHERE Row BETWEEN 1 AND 10

This will provide both paging and a count in 1 query.这将在 1 个查询中提供分页和计数。 You could also use a CASE statement to only do the count at certain times.您还可以使用 CASE 语句仅在特定时间进行计数。 For instance does the count change while users are paging through?例如,当用户翻页时计数是否会发生变化?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM