Я использую этот код, чтобы вызвать функцию SQL, которая возвращает данные из таблицы базы данных SQL ServerSqlCommand.ExecuteReader стал очень медленно
string cmd = String.Format("select * from dbo.GetData(@userId, @fileId, @created);");
using (SqlConnection conn = new SqlConnection(connectionString))
{
if (conn.State != ConnectionState.Open)
conn.Open();
SqlCommand command = new SqlCommand(cmd, conn);
if (String.IsNullOrEmpty(userId))
command.Parameters.AddWithValue("@userId", DBNull.Value);
else
command.Parameters.AddWithValue("@userId", userId);
if (String.IsNullOrEmpty(fileId))
command.Parameters.AddWithValue("@fileId", DBNull.Value);
else
command.Parameters.AddWithValue("@fileId", docId);
command.Parameters.AddWithValue("@created", created);
internalWatch.Reset();
internalWatch.Start();
IDataReader reader = command.ExecuteReader();
table = GetDataTableFromDataReader(reader);
reader.Close();
reader.Dispose();
conn.Close();
internalWatch.Stop();
В таблице я работаю с содержит немного больше, чем 1500000 и должны возвращать бит более 250 тыс. записей.
Если я выполняю функцию SQL в SSMS, для возврата результатов требуется 8 секунд, и я уже использовал код выше на прошлой неделе, чтобы получить результаты в своем рабочем приложении. В это время все было в порядке. Для получения результатов требуется код от 10 до 12 секунд.
Странно, что на сегодняшний день для выполнения тех же результатов требуется более 40 секунд, но я ничего не изменяю в функции SQL или самом коде. Единственное изменение, которое я сделал в моей программе, - это добавить еще несколько классов, которые не имеют никакого отношения к приведенному выше коду.
Если я отладки кода, я могу видеть, что линии
IDataReader reader = command.ExecuteReader();
необходимо большую часть времени.
Поскольку я ничего в функции SQL или сам код не изменится, я не могу понять, почему он так долго теперь ...
И если нужно, здесь функцию SQL, я я использую:
ALTER FUNCTION [dbo].[GetData]
(@userId varchar(128) = NULL,
@fileId varchar(192) = NULL,
@created DateTimeOffset(7))
RETURNS TABLE
AS
RETURN (
WITH FindNewestVersion AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITINO BY FileId, UserId
ORDER BY created DESC) rn
FROM
table1
)
SELECT
q.Created, q.Updated, q.FileId, q.UserId,
F.column1, F.column2, F.column3
FROM
table2 AS F
INNER JOIN
table1 AS q ON F.column4 = q.PersonId AND F.created = q.created
INNER JOIN
(SELECT
created, PersonId, DocumentId
FROM
FindNewestVersion
WHERE
rn = 1) AS x ON q.created = x.created
AND q.PersonId = x.PersonId
AND q.FileId = x.FileId
WHERE
(F.column1 = 'Sample')
AND (q.Created <= @created)
AND (q.Updated >= @created)
AND Q.PersonId = ISNULL(@userId, Q.PersonId)
AND Q.FileId = ISNULL(@fileId, Q.FileId)
)
Благодарим за любые предложения!
Это звучит как параметр sniffing. Если входной параметр UserId равен NULL, будет ли параметр fileID равно null? – DB101
Нет, они отделены друг от друга. Таким образом, возможно, что userId имеет значение null, а fileId имеет значение и наоборот. Создается единственный параметр, который всегда требует значения. – Echelon
Выполнено ли время выполнения в SSMS? – Andreas