我可以在执行存储过程之前获取rowcount吗?

时间:2008-10-31 15:38:11

标签: c# sql-server-2005 stored-procedures visual-studio-2005 count

我有一些复杂的存储过程可能会返回数千行,并且需要很长时间才能完成。

有没有办法找出在查询执行和获取数据之前要返回多少行?

这适用于Visual Studio 2005,Winforms应用程序和SQL Server 2005。

11 个答案:

答案 0 :(得分:6)

您提到您的存储过程需要很长时间才能完成。在从数据库中选择行或将行返回给调用者的过程中,大部分时间是占用的吗?

如果是后者,也许您可​​以创建SP的镜像版本,只获取计数而不是实际行。如果它是前者,那么,你可以做的事情真的不多,因为它是找到合格行的行为,这很慢。

答案 1 :(得分:0)

使存储过程首先计算行数。

SELECT COUNT(*)FROM table

答案 2 :(得分:0)

除非您的应用程序的业务逻辑的某些方面允许计算此,否则。它将不得不做所有的地方和数据库。加入逻辑来弄清楚行的行数,这是SP花费的绝大部分时间。

答案 3 :(得分:0)

如果不执行该过程,则无法获取过程的行计数。

您可以创建一个接受相同参数的不同过程,其目的是告诉您其他过程应返回多少行。但是,只要执行主程序,此程序所需的步骤通常与主程序的步骤非常相似。

答案 4 :(得分:0)

您必须编写不同版本的存储过程才能获得行计数。这个可能会快得多,因为您可以消除未被过滤的连接表,删除排序等。例如,如果您的存储过程执行了sql,例如:

select firstname, lastname, email, orderdate  from 
customer inner join productorder on customer.customerid=productorder.productorderid
where orderdate>@orderdate order by lastname, firstname;

你的计算版本会是这样的:

select count(*) from productorder where orderdate>@orderdate;

答案 5 :(得分:0)

不一般。

通过有关存储过程操作的知识,您可以获得估计或准确计数(例如,如果查询的“核心”或“基础”表能够快速计算,但它是复杂的连接和/或摘要,它们会使时间向上)。

但你必须首先调用计数SP,然后调用数据SP,或者你可以使用多个结果集SP来查看。

答案 6 :(得分:0)

获取行数可能需要一段时间才能获得实际数据,因此在大多数情况下我不会建议执行计数。

一些可能性:

1)SQL Server是否以某种方式公开其查询优化结果?即你能解析查询然后获得行数的估计吗? (我不知道SQL Server)。

2)也许根据用户给出的标准,您可以对自己进行一些估算。例如,如果用户在客户姓氏字段中输入“S%”来查询订单,则可以确定其与客户记录的7%(比如说)匹配,并推断查询可能返回7%的订单记录。

答案 7 :(得分:0)

您的问题的解决方案可能是重写存储过程,以便将结果集限制为某个数字,例如:

SELECT TOP 1000 * FROM tblWHATEVER

在SQL Server中,或

SELECT * FROM tblWHATEVER WHERE ROWNUM <= 1000
在Oracle中

。或者实现一个分页解决方案,以便每个调用的结果集都可以接受。

答案 8 :(得分:0)

继续Tony Andrews在他的回答中所说的,您可以通过以下方式获得查询调用的估计查询计划:

SET showplan_text OFF
GO
SET showplan_all on
GO
--Replace with call you your stored procedure
select * from MyTable
GO 
SET showplan_all ofF
GO

这应该返回一个表或许多表,这些表可以让您获得查询的估计行数。

答案 9 :(得分:0)

您需要分析返回的数据集,以确定返回的结果集的逻辑(有意义)主键是什么。一般来说,这将比完整的过程快得多,因为服务器没有从每个表的每一行的所有列中的数据构建结果集,它只是计算行...通常,它可能不均匀需要读取磁盘上的实际表行来执行此操作,它可能只需要计算索引节点...

然后编写另一个SQL语句,该语句只包含生成这些键列所需的表(希望这是主sql查询中表的一个子集),以及具有相同过滤谓词值的相同where子句... < / p>

然后将另一个Optional参数添加到Stored Proc,例如@CountsOnly,默认值为false(0),因为......

Alter Procedure <storedProcName>
@param1 Type, 
-- Other current params
@CountsOnly TinyInt = 0
As
Set NoCount On

   If @CountsOnly = 1
       Select Count(*) 
       From TableA A 
          Join TableB B On   etc. etc...
       Where < here put all Filtering predicates >

   Else
      <Here put old SQL That returns complete resultset with all data>

  Return 0

然后,您可以调用相同的存储过程,并将@CountsOnly设置为等于1以获取记录数。调用proc的旧代码仍然可以像以前一样运行,因为参数值设置为默认值为false(0),如果不包含

答案 10 :(得分:0)

至少在技术上可以运行将结果集放在临时表中的过程。然后,您可以在将数据从服务器移动到应用程序之前找到行数,并且可以节省必须两次创建结果集。

但是我怀疑除非创建结果集花费很长时间,否则它是值得的。在这种情况下,临时表可能会有问题。几乎可以肯定,通过网络移动大桌面的时间将是创建它的时间的很多倍。