У меня есть запрос, подобный следующему:
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-значных числительных c строковых элементов.
Мое единственное предположение, что это имеет какое-то отношение к очистке значений параметров, но выполнение запроса в сотни раз дольше кажется чрезмерным. Что я сделал, так это добавил свою собственную проверку, чтобы убедиться, что все строки имеют 100% -ное число c, что, как мне кажется, должно предотвратить SQL атаки с использованием инъекций.
Мой код Npg Sql выглядит как это:
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}');
Является ли медлительность только из-за очистки, или ошибка в Npg Sql или что-то еще?