SQL Server 2005
我在DB中有1000万行,并运行一个select(有很多“where”和关节......非常复杂)。结果以网格形式呈现(想想goolge结果),因此,用户不可能使用超过1000个结果。
所以我用一个TOP 1000来限制我的SQL。
问题:用户仍然想知道他的搜索结果有5432个。
我是否可以在不付出代价的情况下获得该信息(换句话说,仍然获得“前1000名”给我的速度优势?)
假设 - 假设TOP 1000带来1000个 100K 行。因此,即使是移动100K的网络价格也可能是一个问题。
结论 天下没有免费的午餐!你可以得到优雅的方式(接受的答案),但它仍然需要更昂贵的操作(即计算所有结果)。 在现实生活中,我将使用2 SQL方法,一个返回前1000行进行显示,一个是ASYNC,并使用count(*)结果更新一些AJAX面板,这将花费更长的时间到计算机
答案 0 :(得分:10)
SELECT TOP 1000 x, y, z, COUNT(*) OVER () AS TotalCount
FROM dbo.table
答案 1 :(得分:5)
就个人而言,我会选择两个声明来访问数据库。一个用于检索计数,一个用于检索前1000个记录。
您可以批量运行两个查询,通过保存到数据库的往返来挤出一些额外的性能。
-- Get the count
select count(*) from table where [criteria]
-- Get the data
select [cols] from table where [criteria]
答案 2 :(得分:3)
您想使用“计数”和分组依据,请查看此参考:http://msdn.microsoft.com/en-us/library/ms175997.aspx
此外,您的问题似乎发布在此处:http://www.eggheadcafe.com/software/aspnet/32427870/select-top-n-plus-a-count.aspx
祝你好运
答案 3 :(得分:0)
您可能过高估计了“前1000名”的表现优势,特别是如果总成绩只有5000左右。
服务器已经必须完成所有连接和填充(这通常是困难的部分),然后必须按照您指定的方式对结果集进行排序,然后最终获得1000个第一个结果。
这里有两个选项:
1)使用Count(*)执行一次查询以获取结果计数,然后使用前1000次执行第二次查询,检索相应的列(如Neil建议的那样)。或
2)第一次检索所有行,将它们缓存在结果集中,然后只向用户显示1000行。
听起来第一个会更快,但第二个只需要打一次数据库,并且根据数据库和查询的具体情况,可能会更好(只要数据库不会返回100,000行!)
答案 4 :(得分:0)
由于您使用的是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)
重新编译就在那里,因为搜索条件可能会在对存储过程的调用之间发生巨大变化,从而导致缓存的查询计划变坏。希望参数/变量是显而易见的。这是一个分页搜索解决方案。系统max rows变量是硬编码的,因此即使应用程序也无法覆盖可返回的最大行数并使服务器崩溃。要获得前1000名,您将传入@page_number = 1和@rows_per_page = 1000。
答案 5 :(得分:-2)
这不会回答你的问题,但我认为这是一个很好的案例,我们实施了:
规则。
是的,执行两个查询(一个计数,一个选择*)不是最佳解决方案(您可以在一个查询中执行此操作!)。但是,如果肯定你将会成为一个瓶颈?
我对这些问题感到困惑,我必须自己记住这个问题才能继续发展。
写得快,写得更好,简介,然后写得最好。
或者,这个可能是瓶颈,这就是你问的原因。但在我看来,如果它是你的瓶颈,更好的优化将重组数据库,以便简化你的查询本身。