【问题标题】:Batching separate prepared npgsql commands批处理单独准备好的 npgsql 命令
【发布时间】:2018-11-13 16:52:41
【问题描述】:

假设你准备了三个 NpgsqlCommands。因为它们必须分开执行。但有时必须同时执行两个或所有三个(嗯,一个接一个)。

有没有办法通过单次往返服务器来批处理和重用这些先前准备好的命令? (目标是尽量减少延迟)

现在我使用第四个命令和分号分隔原始三个命令的副本,并准备这个 - 但我假设这将在服务器上使用更多资源,并在 npgsql 客户端使用更多 SQL 解析。

【问题讨论】:

    标签: npgsql


    【解决方案1】:

    Npgsql 通过在 CommandText 中包含多个语句来支持批处理,用分号分隔。这些在单个网络往返中执行,也可以准备:

    cmd.CommandText = "SELECT ...; UPDATE ...";
    cmd.Prepare();
    

    在内部,Npgsql 将这些命令用分号拆分,并分别准备每个语句(PostgreSQL 实际上并不识别批处理,只识别单个语句)。此外,Npgsql 在逐个语句级别上管理准备好的语句,并且知道重用已经存在的语句。这意味着如果您准备两个包含相同语句的命令,这些语句将共享相同的服务器端准备语句资源。

    【讨论】:

    • 我当前的“单独”已经存在的准备好的命令都有一个名为“@pkey”的参数——当批量执行其中两个时,每个@pkey 可能需要自己的唯一值。我相信批处理命令只有一组参数?在这种情况下,我是否必须为“@pkey”提供我原来的三个命令的唯一名称,以获取重用的预准备语句和每个命令的 unqiue 参数值?换句话说,参数名称会影响重用现有语句的机制吗?感谢您的见解。
    • 不,参数名称不会影响任何事情。实际上,PostgreSQL 不支持参数名称,只支持位置占位符:$1、$2。由于在 ADO.NET 中标准是命名占位符,Npgsql 解析您的 SQL 并用位置占位符 ($1) 替换命名占位符 (@pkey),并且准备好的语句缓存仅在此之后启动;因此,对于准备好的语句,仅缓存带有位置占位符的版本处理版本很重要。
    • 使用 Wireshark 检查协议是真正了解正在发生的事情的好方法 - 您可以看到 Npgsql 发送到 PostgreSQL 的实际 SQL,以及哪些语句已准备好,哪些未准备好,以及使用了哪个预处理语句名称(指示缓存并确定有多少服务器端对象正在使用)。
    猜你喜欢
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    相关资源
    最近更新 更多