Тайм-аут запросов в SP, но работает нормально в анализаторе запросов - PullRequest
1 голос
/ 23 сентября 2010

Мне кажется, что в SQL 2008 возникла странная проблема.

У меня есть запрос, который работает нормально и быстро из анализатора запросов, но истекает время, если выполняется через хранимую процедуру! SP только начинается с этого запроса и не имеет другого кода перед этим запросом

SELECT col1,col2 FROM TBL1 (nolock)
INNER JOIN TBL2 (nolock) 
ON tbl1.col=LEFT(tbl2.col1,LEN(tbl2.col1)-2) AND tbl1.col2=RIGHT(tbl2.col1,2)
AND tbl1.col4=2233
AND tbl1.date1 BETWEEN tbl2.date1 and isnull(tbl2.date2,getdate())

Обратите внимание, что на самом деле tbl1 - это представление, в котором col и col2 поступают через самостоятельное соединение. Также в соответствии с бизнес-требованиями, tbl2.col1 должен иметь объединенное значение. Если требуется решить эту проблему, я могу изменить свое мнение.

Ответы [ 2 ]

2 голосов
/ 24 сентября 2010

В качестве дополнительной проблемы обратите внимание, что если вы можете сделать некоторые предположения о длине строки, ваше выражение объединения может быть упрощено (и, возможно, получит лучшую производительность, поскольку одна сторона теперь использует равенство):

SELECT tbl1.col1, tbl1.col2
FROM
   TBL1
   INNER JOIN TBL2

      ON tbl1.col + tbl1.col2 = tbl2.col1
      AND tbl1.col4=2233
      AND tbl1.date1 BETWEEN tbl2.date1 AND Coalesce(tbl2.date2, GetDate())

Кроме того, если вы ищете лучшую производительность, попробуйте это:

ALTER TABLE TBL2 ADD LeftPart AS (LEFT(col1, LEN(col1)-2));
ALTER TABLE TBL2 ADD RightPart AS (RIGHT(tbl2.col1,2));
CREATE NONCLUSTERED INDEX IX_TBL2_Parts ON TBL2 (LeftPart, RightPart);

Теперь вы можете просто присоединиться так:

SELECT tbl1.col1, tbl1.col2
FROM
   TBL1
   INNER JOIN TBL2
      ON tbl1.col = tbl2.LeftPart
      AND tbl1.col2 = tbl2.RightPart
      AND tbl1.col4=2233
      AND tbl1.date1 BETWEEN tbl2.date1 AND Coalesce(tbl2.date2, GetDate())

Еще лучше измените дизайн базы данных, чтобы фактически хранить данные TBL2.col1 в двух столбцах.Вы нарушаете первую нормальную форму, помещая два отдельных фрагмента данных в один столбец, и теперь, когда вы обнаруживаете, вы платите за это во всем приложении с точки зрения производительности, времени разработки и обслуживания, сложности запросов ии т. д.

Можно даже изменить мою схему, чтобы столбцы LeftPart и RightPart были действительными, и вы создали новый вычисляемый столбец с именем Col1, с индексом, чтобы материализовать значения и сделать их доступными для поиска.Наконец, если это абсолютно необходимо, вы можете переименовать таблицу, создать представление для таблицы, используя старое имя, а затем поместить триггеры INSTEAD-OF в представление, чтобы перехватывать операции с данными над таблицей и переводить их в правильную схему.

Обновление

Кстати, если вы имеете какое-либо влияние на дизайн таблицы, вы можете рассмотреть вопрос об использовании значения «дата окончания срока действия» «99991231» или чего-то подобногодля tbl2.date2, а не NULL.Эта Coalesce может снизить производительность, иногда вызывая сканирование, когда поиск был бы возможен.

1 голос
/ 23 сентября 2010

В прошлом я сталкивался с подобными ситуациями, вызванными прослушиванием параметров . Вы можете попробовать метод, рассмотренный в статье выше, и посмотреть, имеет ли это значение.

Что происходит, когда вы запускаете хранимую процедуру в первый раз, SQL Server кэширует свой план выполнения и использует его в дальнейшем. Если вы запустите сохраненный процесс с параметрами, которые делают этот план выполнения неоптимальным, вы увидите поведение, которое вы описываете.

Вы также можете использовать подсказку запроса recompile, чтобы убедиться, что он использует новый план выполнения при каждом выполнении. Для этого вы должны добавить OPTION(RECOMPILE) в конец вашего запроса:

SELECT id, name 
from tableName
WHERE id between @min and @max
OPTION(RECOMPILE);

Эта ссылка содержит несколько решений для проблемы перехвата параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...