Почему я получаю сообщение об ошибке Timeout Expired при выполнении этого запроса?

Я запускаю этот запрос на SQL Server 2008 с использованием ODBC. Если я уберу последнюю часть (ИЛИ li.DATEGENERATED >= (...))), тогда я не получу ошибку... но я могу просто запустить ее в SSMS.

SELECT COUNT(*) FROM dbo.POITEMST li
 WHERE (? IS NULL OR li.DATEGENERATED >= ?)
   AND (? IS NULL OR (li.DATEGENERATED >= (
    SELECT MAX(t.DATEGENERATED) FROM dbo.POITEMST t WHERE t.PONUM = ?)))

Вот как я устанавливаю параметры

DbParameter startDateParam = cmd.CreateParameter();
startDateParam.ParameterName = "StartDate";
startDateParam.Value = (StartDate.HasValue ? (object)StartDate.Value : (object)(new DateTime(1753, 2, 2)));
cmd.Parameters.Add(startDateParam);

startDateParam = cmd.CreateParameter();
startDateParam.ParameterName = "StartDate";
startDateParam.Value = (StartDate.HasValue ? (object)StartDate.Value : (object)(new DateTime(1753, 2, 2)));
cmd.Parameters.Add(startDateParam);

DbParameter startPoParam = cmd.CreateParameter();
startPoParam.ParameterName = "StartPO";
startPoParam.DbType = DbType.String;
startPoParam.Value = (string.IsNullOrEmpty(StartPurchaseOrder) ? (object)DBNull.Value : (object)StartPurchaseOrder);
cmd.Parameters.Add(startPoParam);

startPoParam = cmd.CreateParameter();
startPoParam.ParameterName = "StartPO";
startPoParam.DbType = DbType.String;
startPoParam.Value = (string.IsNullOrEmpty(StartPurchaseOrder) ? (object)DBNull.Value : (object)StartPurchaseOrder);
cmd.Parameters.Add(startPoParam);

РЕДАКТИРОВАТЬ: эти даты указаны только там, потому что я пытался понять это... раньше он проходил в DBNull, если не было даты начала.


person Max Schmeling    schedule 02.05.2009    source источник


Ответы (4)


Разделяй и властвуй. Начните с T-SQL с жестко закодированными значениями, как NULL, так и ненулевыми. Начните с самого простого запроса и наращивайте его, изучая план запроса на каждом этапе. Вы можете обнаружить, что у вас есть проблемы с индексацией и т. д. Устраните их, а затем вернитесь к коду.

Очень сложно помочь одним запросом без дополнительной информации о схеме - макеты таблиц, индексы и т. д.

person n8wrl    schedule 19.05.2009

Сколько времени ушло на запуск в ssms? Если вы можете запустить запрос с включенным планом выполнения (меню запроса, план выполнения — не предполагаемый). Если есть проблема с индексом, это должно сообщить вам об этом на панели плана выполнения.

Можете ли вы или ваш администратор базы данных запустить профилировщик SQL; и зафиксируйте то, что на самом деле передается на сервер sql, чтобы подтвердить, что оно соответствует вашим ожиданиям.

person u07ch    schedule 02.05.2009
comment
Он работает быстрее, чем я могу мигать в SSMS... Я мог бы запустить профилировщик, но это не стоит усилий... Я уже потратил слишком много часов, поэтому я собираюсь сделать это по-другому. - person Max Schmeling; 05.05.2009

Я думаю, вы можете реорганизовать свой запрос для повышения производительности:

SELECT COUNT(*) FROM dbo.POITEMST li
WHERE li.DATEGENERATED >= ISNULL(?,'1753-02-02')
AND li.DATEGENERATED >= ISNULL((SELECT MAX(t.DATEGENERATED) FROM dbo.POITEMST t WHERE t.PONUM = ?), '1753-02-02')

Сочетание сравнения с нулевым значением с ИЛИ выглядит частью проблемы.

Надеюсь это поможет,

Билл

person V'rasana Oannes    schedule 19.05.2009

Сделайте следующее:

  1. Рефакторинг запроса
  2. Превратите это в хранимую процедуру
  3. Создайте индексы для соответствующих столбцов

По моему опыту, индексы имеют огромное значение, когда возникают различия в производительности между SSMS и ODBC для одного и того же запроса.

person Community    schedule 07.09.2009