c# - 为什么将数组作为文字而不是参数传递要快得多?

标签 c# postgresql npgsql

我有如下查询:

SELECT
   table1.field1,
   table1.field2,
   table3.field1,
   table3.field2,
   table3.field3,
   table3.field4

FROM table1

INNER JOIN table2
ON table1.field1 = table2.field1

INNER JOIN table3
ON table2.field2 = table3.field5

WHERE table1.field1 = ANY(@pArray);

所有这些比较都是针对字符串/文本字段。所有外键字段都有索引。这是一个设计不佳的数据库,我几乎只能对其进行只读访问。

我想知道的是为什么上述参数导致此查询花费 10 多秒,而如果我将数组作为数组文字手动传递(使用字符串连接),则大约需要 40-50 毫秒。

我的数组包含 195 个 8 字符数字字符串元素。

我唯一的猜测是它与清理参数值有关,但让查询花费数百倍的时间似乎有点过分。我所做的是添加我自己的检查以确保所有字符串都是 100% 数字,我认为这应该避免 SQL 注入(inject)攻击。

我的 NpgSql 代码如下所示:

void MyQuery(
   string[] pArray
) {
   var sql = @"
      // as above
   ";

   using var connection = new NpgsqlConnection(mConnectionString);
   connection.Open();

   using var command = new NpgsqlCommand(sql, connection);
   command.Parameters.AddWithValue("pArray", pArray);

   // takes ~12 seconds with parameter, or ~50ms with array literal
   using var reader = command.ExecuteReader();

当删除参数时,WHERE 子句在连接后看起来更像这样:

WHERE table1.field1 = ANY('{12345678,12345679,12345680,12345681}');

缓慢仅仅是由于清理、NpgSql 中的错误或其他原因造成的吗?

最佳答案

评论中指出的问题是在没有指定类型的情况下添加参数。将参数行更改为以下内容解决了问题:

command.Parameters.AddWithValue("pArray", NpgsqlDbType.Array | NpgsqlDbType.Char, pArray);

请注意,要指定数组类型,您可以将 Array 值与另一个值(在本例中为 Char)进行或运算。数据库中的实际 PostgreSQL 类型类似于 character varying(15)

关于c# - 为什么将数组作为文字而不是参数传递要快得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61551325/

相关文章:

C# 无法从 API 调用读取 json 响应

postgresql - 关系数据库管理系统 : Is there a performance hit for co-locating columns that are not usually queried together?

c# - 无法检索连接 MVC3 EF 与 Postgres 9.1 的元数据

entity-framework - 如何在 EF Core 中实现 Select For Update

postgresql - Npgsql.PostgresException (0x80004005) : XX000: cache lookup failed for type 207852 when schema dropped

c# - JavaScript 中的 MVC C# 代码

c# - 为什么这个 C# 代码没有编译?

c# - DotLiquid/Liquid 获取字典

javascript - 如何修复我的情况下的无效 JSON?

sql - 如何在多个连接行需要包含内容的情况下执行 SQL JOIN