Sql 选择Top1000,但知道有多少行吗?

Sql 选择Top1000,但知道有多少行吗?,sql,sql-server-2005,performance,Sql,Sql Server 2005,Performance,SQL Server 2005 我在DB中有1000万行,并且运行了一个包含很多where和joint的select。。相当复杂。结果显示在grid think goolge结果中,因此,用户不可能使用超过1000个结果 因此,我将SQL限制为前1000个 问题:用户仍然想知道他的搜索有5432个结果 我能在不付出代价的情况下获得这些信息吗?换句话说,我还能获得1000强给我的速度优势吗 假设 -假设前1000行带来了100K行中的1000行。因此,即使是移动10万的网络价格也可能是一个问题 结

SQL Server 2005

我在DB中有1000万行,并且运行了一个包含很多where和joint的select。。相当复杂。结果显示在grid think goolge结果中,因此,用户不可能使用超过1000个结果

因此,我将SQL限制为前1000个

问题:用户仍然想知道他的搜索有5432个结果

我能在不付出代价的情况下获得这些信息吗?换句话说,我还能获得1000强给我的速度优势吗

假设 -假设前1000行带来了100K行中的1000行。因此,即使是移动10万的网络价格也可能是一个问题

结论 没有免费的午餐!您可以通过优雅的方式获得公认的答案,但它仍然需要与更昂贵的操作(即计算所有结果)一样长的时间。
在现实生活中,我将使用2种SQL方法,一种是返回前1000行以供显示,另一种是异步的,并使用count*结果更新一些AJAX面板,这将花费计算机更长的时间

就我个人而言,我会选择两条语句来访问数据库。一个用于检索计数,一个用于检索前1000条记录

您可以批量运行这两个查询,通过节省到数据库的往返时间来压缩一点额外的性能

-- Get the count
select count(*) from table where [criteria]

-- Get the data
select [cols] from table where [criteria]

如果要使用计数和分组依据,请签出此引用:

您的问题似乎也发布在这里:


祝你好运

你可能高估了前1000名的绩效优势,尤其是如果总共只有约5000个结果的话

服务器已经完成了所有的连接和工作,这通常是最困难的部分,然后必须按照您指定的方式对结果集进行排序,最后获得1000个第一个结果

这里有两个选项:

1使用Count*进行一次查询以获得结果的计数,然后使用前1000名进行第二次查询,按照Neil的建议检索适当的列。或 2第一次检索所有行,将它们缓存在结果集中,然后仅向用户显示1000行


听起来第一个可能会更快,但第二个只需访问数据库一次,并且根据数据库和查询的具体情况,如果数据库不返回100000行,可能会更好

由于您使用的是SQL Server 2005,因此可以使用CTE进行此类查询。以下是我目前为客户所做的工作:

;WITH Search_Results AS
(
     SELECT TOP(@system_max_rows)
          my_column1,
          my_column2,
          ROW_NUMBER() OVER
          (
               ORDER BY
                    -- Your order criteria here
          ) AS row_num,
          COUNT(my_column1) OVER (PARTITION BY '') As total_count
     FROM
          My_Table
     -- Put any joins here
     WHERE
          -- Put WHERE criteria here
)
SELECT
     my_column1,
     my_column2,
     row_num,
     total_count
FROM
     Search_Results
WHERE
     ((row_num - 1)/@rows_per_page) + 1 = CASE
                WHEN ((total_count - 1)/@rows_per_page) + 1 < @page_number THEN ((total_count - 1)/@rows_per_page) + 1
                ELSE @page_number
           END
OPTION (RECOMPILE)

重新编译之所以存在,是因为在调用存储过程之间,搜索条件可能会发生剧烈变化,从而导致缓存的查询计划变差。希望参数/变量是显而易见的。这是一个分页搜索解决方案。system max rows变量是硬编码的,因此即使是应用程序也无法覆盖可返回的最大行数并使服务器崩溃。要获得前1000名,您需要通过@page\u number=1和@rows\u per\u page=1000。

这不会回答您的问题,但我认为这是一个很好的案例,我们可以实现:

硬件很便宜 程序员并不便宜 规则

是的,做两个查询一个计数,一个选择*不是一个最佳解决方案您可以在一个查询中完成它!。但你有多确定这会成为瓶颈

我被这些问题困住了,我必须记住这一点才能继续发展

写得快,写得好,写得好,写得好,写得好


或者,也许这就是瓶颈,这就是为什么你要问。但在我看来,如果这是您的瓶颈,更好的优化方法是重新构造数据库,以便简化查询本身。

如果您愿意,也可以将这两个合并。或者将它们放在存储过程中。除非它们具有相同的列数和列类型,否则不能合并它们,这是不太可能的。这是一种错误的优化和常见的误解,但使用countPK,而不是count*.Greg。在性能上没有区别。Countanything只计算行数、周期数,优化器知道这一点。@Neil-这可以在SQL 2005的一个简单语句中完成。不需要两个查询。那么您肯定不想在客户端缓存它们!好问题,有人应该按Mark作为答案;别傻了。我不会浪费任何人的时间。我敢肯定!从数千万行的数据库返回10万行需要10分钟。只需几秒钟就能进入前1000名。所以是的,这是一个真正的问题,值得我的程序员花时间,没有硬件升级可以解决它。非常聪明-谢谢。更多示例如下:
SELECT TOP 1000 x, y, z, COUNT(*) OVER () AS TotalCount
FROM dbo.table