问题很简单。我有以下SQL:
SELECT *
FROM T1
SELECT *
FROM T2
SELECT *
FROM T3
SELECT *
FROM T4
在一个案例中,我需要所有四个数据集,而在另一个案例中,我只需要T1
和T2
。
我应该编写另一个仅返回T1
和T2
的存储过程,还是可以跳过最后两个数据集(不在SQL引擎上执行批处理)。
我的意思是,如果我仅使用以下代码
获取T1
和T2
var reader = command.ExecuteReader();
ReadSet1();
reader.NextResult();
ReadSet2();
reader.Close()
SQL Server是否实际执行T3
和T4
?
答案 0 :(得分:2)
读者只能读到目前为止
它可以启动NextResult();但它不会全部执行,除非它适合缓冲区
试试这个
读完T1后,改变T4中的值
您将看到新值(除非行数低)
如果SQL在开始时全部运行
您还可以返回getdate以获取何时获取行的度量
答案 1 :(得分:0)
由于SQL Server不知道您在应用程序中对结果集执行了什么操作,因此无论您是否需要,它都将准备所有结果集。至少我是这么认为的。
您可以打开Profiler来监控SELECT
发生的那一刻,一次或一个接一个......但我很确定,该程序适用于所有人。
您可以:
为每个SELECT
创建一个过程(实际上更好的是内联表值函数)。这是 - 当然! - 更好,更清洁的方法,但可能会对调用应用程序的代码产生很大影响。或
传递@LoadT1 BIT, @LoadT2 BIT...
等参数并在IF
之后加载。在C#-code中,可能存在执行调用的现有函数或方法。只需为此函数提供4个具有默认值的布尔参数(可选参数)。不必更改任何现有代码。但是如果这有意义,你可以设置适当的参数。
答案 2 :(得分:0)
ExecuteReader将完整执行proc。如果您观看分析器并在代码之间放置延迟,您将会看到。你所拥有的其他步骤并不是针对proc,它们是以读者的形式反对proc的执行结果。
你应该做的是意见和权衡问题。一方面,如果你使用相同的proc,你可以获得代码重用的优势,如果需要为数据集1或2修改某些内容,可以改变代码的一半。另一方面,如果你将它们分开(或者两个过程或四个)你有效率的优势。所以这真的归结为查询的成本是多少......至少这对我来说是个决定因素。一般来说,我会说最好的方法就是有4个单独的触发器,但如果它们真的是影响较小的查询,我就不知道我会花时间。
Shnugo提出的另一个选择是拥有一个或多个参数......比如说@ returnAll4 BIT。应用程序将通过它,如果它为0 / false,您可以通过对它们放置WHERE @ returnAll4 = 1过滤器来避免执行第3和第4个数据集。您仍然可以在执行计划中看到这些内容,但除了过滤器评估之外,他们实际上不会做任何其他事情。我已经使用了这种方法,但我倾向于远离它,因为我担心未来对另一位开发人员来说可能有点不清楚。