为什么将数组作为文字而不是参数传递的速度如此之快?

问题描述 投票:3回答:1

我有如下查询:

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注入攻击。

我的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中的错误或其他原因?

c# postgresql npgsql
1个回答
0
投票

注释中指出的问题是添加了一个参数,但未指定类型。将参数行更改为以下内容可以解决问题:

© www.soinside.com 2019 - 2024. All rights reserved.