只获取几个结果集
Fetching only several result sets
问题很简单。我有以下 SQL:
SELECT *
FROM T1
SELECT *
FROM T2
SELECT *
FROM T3
SELECT *
FROM T4
在一种情况下我需要所有四个数据集,在其他情况下我只需要 T1
和 T2
。
我应该编写另一个 returns 仅 T1
和 T2
的存储过程,还是我可以跳过最后两个数据集(不在 SQL 引擎上执行批处理)。
我的意思是,如果我使用以下代码只获取 T1
和 T2
var reader = command.ExecuteReader();
ReadSet1();
reader.NextResult();
ReadSet2();
reader.Close()
SQL 服务器是否实际为 T3
和 T4
执行批处理?
由于 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 获取行的获取日期
问题很简单。我有以下 SQL:
SELECT *
FROM T1
SELECT *
FROM T2
SELECT *
FROM T3
SELECT *
FROM T4
在一种情况下我需要所有四个数据集,在其他情况下我只需要 T1
和 T2
。
我应该编写另一个 returns 仅 T1
和 T2
的存储过程,还是我可以跳过最后两个数据集(不在 SQL 引擎上执行批处理)。
我的意思是,如果我使用以下代码只获取 T1
和 T2
var reader = command.ExecuteReader();
ReadSet1();
reader.NextResult();
ReadSet2();
reader.Close()
SQL 服务器是否实际为 T3
和 T4
执行批处理?
由于 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 获取行的获取日期