只获取几个结果集

Fetching only several result sets

问题很简单。我有以下 SQL:

SELECT *
FROM T1

SELECT *
FROM T2

SELECT *
FROM T3

SELECT *
FROM T4

在一种情况下我需要所有四个数据集,在其他情况下我只需要 T1T2。 我应该编写另一个 returns 仅 T1T2 的存储过程,还是我可以跳过最后两个数据集(不在 SQL 引擎上执行批处理)。

我的意思是,如果我使用以下代码只获取 T1T2

var reader = command.ExecuteReader();
ReadSet1();
reader.NextResult();
ReadSet2();
reader.Close()

SQL 服务器是否实际为 T3T4 执行批处理?

由于 SQL 服务器不知道您在应用程序中对结果集做了什么,因此无论您是否需要,它都会准备所有结果集。至少我是这么认为的。

您可以打开 Profiler 来监控 SELECT 发生的时间,一次或一个接一个地发生...但我很确定,该过程对所有... .

你可能:

  • 为每个 SELECT 创建一个过程(实际上内联 table 值函数更好)。这是 - 当然! - 更好更简洁的方法,但可能会对调用应用程序的代码产生很大影响。或者

  • 传入@LoadT1 BIT, @LoadT2 BIT...等参数,在IF之后加载。在 C# 代码中,可能有一个现有的函数或方法来执行调用。只需给这个函数 4 个带默认值的布尔参数(可选参数)。无需更改任何现有代码。但在这有意义的情况下,您可以设置适当的参数。

ExecuteReader 将执行整个过程。如果您观察探查器并在步骤之间的代码中放置延迟,您将看到这一点。您拥有的其他步骤并不反对 proc,它们以 reader.

的形式反对 proc 的执行结果

你该怎么做,见仁见智,权衡取舍。一方面,如果您使用相同的 proc,您将获得代码重用的优势,并且如果需要为数据集 1 或 2 修改某些内容,则可以将更改代码的地方减少一半。另一方面,如果您将它们分开(分为两个或四个)你有效率的优势。所以这真的归结为查询的成本有多高……至少这对我来说是决定因素。一般来说,我会说最好的方法是有 4 个单独的过程,但如果它们真的是低影响查询,我不知道我会花时间。

Shnugo 提出的另一种选择是具有一个或多个参数……比如 @returnAll4 BIT。该应用程序会通过它,如果它是 0/false,您可以通过在它们上放置一个 WHERE @returnAll4 = 1 过滤器来避免执行第三个和第四个数据集。您仍然会在执行计划中看到它们,但除了过滤器评估之外,它们实际上不会做任何事情。我已经使用过这种方法,但我倾向于远离它,因为我担心将来其他开发人员可能会有点不清楚。

Reader 只会提前阅读这么多

可能会启动NextResult();但它不会全部执行,除非它适合缓冲区

试试这个
读取 T1 后更改 T4 中的值
您将看到新值(除非行数很低)
如果 SQL 运行 all 4 at the start

你将看不到新值

您还可以 return 获取行的获取日期