Улучшенная производительность DROP & CREATE FUNCTION

У меня есть запрос, который был нами WHERE value IN ( SELECT * FROM dbo . Split ( 'SO' , ',' )) ga multi-statement table value function WHERE value = 'SO' WHERE value IN ( 'SO' ) Значение WHERE IN ( SELECT 'SO' ) предложение WHERE как таковое:

CROSS APPLY

Возвращаемое значение функции представляет собой таблицу с одной ячейкой, «SO»

Я нашел запрос намного быстрее без функции:

IN

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

Что могло измениться, когда я упал и воссоздал эту функцию?

sql,sql-server,tsql,sql-server-2014,

1

Ответов: 3


3

Это слишком долго для комментария.

SQL Server компилирует запросы в хранимых функциях и хранимых процедурах при первом вызове. Решения, принятые оптимизатором, основаны на статистике таблицы и параметрах в то время.

Это называется параметром sniffing (я не поклонник этого термина, потому что решения основаны как на параметрах, так и на статистике таблицы).

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

Другим распространенным решением является принудительная перекомпиляция запроса (или запросов) в программном коде. Однако это приводит к накладным расходам на перекомпиляцию. Такие накладные расходы должны быть небольшими для запроса, который занимает минуту, чтобы выполнить, но более значителен, если запрос занимает менее секунды.


0

Я бы использовал вместо предложения:SELECT t.* FROM table t CROSS APPLY (SELECT * FROM dbo.Split('SO',',') ) tt WHERE t.value = tt.col;IN

string

Если у вас есть INбольшой no_sos, то INпредложение даст вам плохую производительность.


0

Пожалуйста, попробуйте Tally Tables вместо UDF и дайте мне знать.

declare @mytbl table (Value varchar(100))
insert into @mytbl values('Element01'),('Element04')

DECLARE @Parameter VARCHAR(8000)
    SET @Parameter = ',Element01,'

IF OBJECT_ID('dbo.tally') is not null
drop table dbo.tally

select TOP (select len(@Parameter)) identity(INT,1,1) AS N INTO TALLY FROM Master.dbo.SysColumns sc1,Master.dbo.SysColumns  c2

select * from @mytbl **where Value in (SELECT sUBSTRING(@Parameter,N+1,CHARINDEX(',',@Parameter,n+1)-n-1)
   FROM dbo.Tally
  WHERE N <= LEN(@Parameter)-1
    AND SUBSTRING(@Parameter,N,1) = ','
  )**

благодаря

SQL, SQL-сервер, TSQL, SQL-сервер 2014,
Похожие вопросы