Size: a a a

SqlCom.ru - Стиль жизни SQL

2020 October 21

Р

Роман in SqlCom.ru - Стиль жизни SQL
Dmitriy Ivanov
лог посмотрите, я не понимаю, что такое база под замком, возможно она redo\undo  делает или какие-то проблемы с логом.
То есть, база ушла в однопользовательский режим, и сделать на нее атачч неполучается
источник

I

ILYA in SqlCom.ru - Стиль жизни SQL
Роман
То есть, база ушла в однопользовательский режим, и сделать на нее атачч неполучается
Через sqlcmd пробуй к ней подсоединиться , студия не даст и там возвращай многопользовательский режим
источник

MC

Max Chistyakov in SqlCom.ru - Стиль жизни SQL
Всем привет.

Есть таблица с такой структурой
create table dbo.ORDERS (ID int, ENABLED int, [CREATIONDATETIME] float, [CLIENTID] float,
[WORKNAME] varchar(100),[WORKPHONE] varchar(100),[FRIEND] varchar(100),[INFO] varchar(100),[ADULTINFO] varchar(100),[WORKHEADMEN] varchar(100)
);

CREATE NONCLUSTERED INDEX [_dta_index_ORDERS_7_1540200537__K19_K6_K18_K1_7_9_16_34_62_63] ON [dbo].[ORDERS]
(
 [CLIENTID] ASC,
 [ENABLED] ASC,
 [CREATIONDATETIME] ASC,
 [ID] ASC
)
INCLUDE([WORKNAME],[WORKPHONE],[FRIEND],[INFO],[ADULTINFO],[WORKHEADMEN]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 95) ON [PRIMARY]
GO

Говорю разработчикам на работе: использовать функции применительно к столбцам в WHERE нельзя, это может привести к сканированию индекса вместо быстрого поиска. На что мне кидают пример запроса по этой таблице:

select o.id from orders o 
where convert(datetime, o.CREATIONDATETIME -2)>= '20201020'
- 2 секунды

select o.id from orders o 
where creationdatetime >= dbo.DateStrToDate('2020-10-20')
- 1 минута.
DateStrToDate
- CLR функция, которая превращает текст в тип float.

В обоих актуал планах используется сканирование индекса _dta_index_ORDERS_7_1540200537__K19_K6_K18_K1_7_9_16_34_62_63, только во втором плане дополнительным шагом идёт итератор FILTER со стоимостью 5%. Статистика по индексу была обновлена перед выполнением запроса, фрагментация - 22%, строк в таблице - 7 млн, значения
creationdatetime
идут с 2012 года по текущий день, с уплотнением начиная с 2018 года. Почему время выполнения двух запросов насколько разное?
источник

MC

Max Chistyakov in SqlCom.ru - Стиль жизни SQL
в мишшинг индекс он предлагает создать индекс по creationdatetime и покрыть поле ID, идея хорошая но мне меня интересует всё же другое
источник

M

Marat in SqlCom.ru - Стиль жизни SQL
Max Chistyakov
Всем привет.

Есть таблица с такой структурой
create table dbo.ORDERS (ID int, ENABLED int, [CREATIONDATETIME] float, [CLIENTID] float,
[WORKNAME] varchar(100),[WORKPHONE] varchar(100),[FRIEND] varchar(100),[INFO] varchar(100),[ADULTINFO] varchar(100),[WORKHEADMEN] varchar(100)
);

CREATE NONCLUSTERED INDEX [_dta_index_ORDERS_7_1540200537__K19_K6_K18_K1_7_9_16_34_62_63] ON [dbo].[ORDERS]
(
 [CLIENTID] ASC,
 [ENABLED] ASC,
 [CREATIONDATETIME] ASC,
 [ID] ASC
)
INCLUDE([WORKNAME],[WORKPHONE],[FRIEND],[INFO],[ADULTINFO],[WORKHEADMEN]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 95) ON [PRIMARY]
GO

Говорю разработчикам на работе: использовать функции применительно к столбцам в WHERE нельзя, это может привести к сканированию индекса вместо быстрого поиска. На что мне кидают пример запроса по этой таблице:

select o.id from orders o 
where convert(datetime, o.CREATIONDATETIME -2)>= '20201020'
- 2 секунды

select o.id from orders o 
where creationdatetime >= dbo.DateStrToDate('2020-10-20')
- 1 минута.
DateStrToDate
- CLR функция, которая превращает текст в тип float.

В обоих актуал планах используется сканирование индекса _dta_index_ORDERS_7_1540200537__K19_K6_K18_K1_7_9_16_34_62_63, только во втором плане дополнительным шагом идёт итератор FILTER со стоимостью 5%. Статистика по индексу была обновлена перед выполнением запроса, фрагментация - 22%, строк в таблице - 7 млн, значения
creationdatetime
идут с 2012 года по текущий день, с уплотнением начиная с 2018 года. Почему время выполнения двух запросов насколько разное?
из за clr функции вестимо
источник

MC

Max Chistyakov in SqlCom.ru - Стиль жизни SQL
Marat
из за clr функции вестимо
да не, не должно быть - там всё просто
ALTER FUNCTION [dbo].[DateStrToDate](@dateStr [nvarchar](4000))
RETURNS [float] WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [medInfodll].[UserDefinedFunctions].[DateStrToDate]

один аргумент - одно значение, функция простая  внутри medInfodll и детерминированная. Время работы с одним аргументом - меньше секунды

да  и насколько помню, планировщик сразу вычисляет значение clr, и использует уже не функцию, а значение как константу.
источник

M

Marat in SqlCom.ru - Стиль жизни SQL
Max Chistyakov
да не, не должно быть - там всё просто
ALTER FUNCTION [dbo].[DateStrToDate](@dateStr [nvarchar](4000))
RETURNS [float] WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [medInfodll].[UserDefinedFunctions].[DateStrToDate]

один аргумент - одно значение, функция простая  внутри medInfodll и детерминированная. Время работы с одним аргументом - меньше секунды

да  и насколько помню, планировщик сразу вычисляет значение clr, и использует уже не функцию, а значение как константу.
ну попробуйте выполнить без нее, укажите явно флоат значение
источник

MC

Max Chistyakov in SqlCom.ru - Стиль жизни SQL
Marat
ну попробуйте выполнить без нее, укажите явно флоат значение
а вы правы
источник

MC

Max Chistyakov in SqlCom.ru - Стиль жизни SQL
Marat
из за clr функции вестимо
почему так? я даже в плане не вижу, чтобы время выполнения функции как-то отображалось
источник

M

Marat in SqlCom.ru - Стиль жизни SQL
Max Chistyakov
почему так? я даже в плане не вижу, чтобы время выполнения функции как-то отображалось
скалярная функция потому что, посмотрите сколько вызовов во время выполнения
источник

MC

Max Chistyakov in SqlCom.ru - Стиль жизни SQL
насколько вижу (точнее, не вижу), вызовы скалярной функции отдельно в плане не показаны
источник

M

Marat in SqlCom.ru - Стиль жизни SQL
Max Chistyakov
насколько вижу (точнее, не вижу), вызовы скалярной функции отдельно в плане не показаны
sys.dm_exec_function_stats
источник

О奧

Олег 奧列格 (Ào liè gé)... in SqlCom.ru - Стиль жизни SQL
Max Chistyakov
да не, не должно быть - там всё просто
ALTER FUNCTION [dbo].[DateStrToDate](@dateStr [nvarchar](4000))
RETURNS [float] WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [medInfodll].[UserDefinedFunctions].[DateStrToDate]

один аргумент - одно значение, функция простая  внутри medInfodll и детерминированная. Время работы с одним аргументом - меньше секунды

да  и насколько помню, планировщик сразу вычисляет значение clr, и использует уже не функцию, а значение как константу.
UDF часто зло...
источник

О奧

Олег 奧列格 (Ào liè gé)... in SqlCom.ru - Стиль жизни SQL
Marat
скалярная функция потому что, посмотрите сколько вызовов во время выполнения
На каждую строчку же
источник

MC

Max Chistyakov in SqlCom.ru - Стиль жизни SQL
Marat
скалярная функция потому что, посмотрите сколько вызовов во время выполнения
я понял, что вы намекаете на такую ситуацию https://www.databasejournal.com/features/mssql/article.php/3845381/T-SQL-Best-Practices-150-Don146t-Use-Scalar-Value-Functions-in-Column-List-or-WHERE-Clauses.htm
но вроде как раз CLR-функции являются исключением из этого правила, и если необходимо использовать функцию в селекте, рекомендуют переделать её на скалярную
источник

MC

Max Chistyakov in SqlCom.ru - Стиль жизни SQL
давно читал в 70-461, сейчас поищу
источник

M

Marat in SqlCom.ru - Стиль жизни SQL
функция у вас прежде всего скалярная, а что она там дергает CLR или нет оптимизатору пофигу
источник

M

Marat in SqlCom.ru - Стиль жизни SQL
sys.dm_exec_function_stats посмотрите сколько у вас execution count и будет понятно
источник

MC

Max Chistyakov in SqlCom.ru - Стиль жизни SQL
а я надеялся, что если аргумент функции - постоянная, то и сама функция выполнится один раз а дальше каждая строка будет сравниваться с полученным результатом
источник

AC

Alexey Chaykin in SqlCom.ru - Стиль жизни SQL
SELECT
  OBJECTPROPERTYEX(OBJECT_ID('dbo.DateStrToDate'), 'IsDeterministic') as IsDeterministic,
  OBJECTPROPERTYEX(OBJECT_ID('dbo.DateStrToDate'), 'SystemDataAccess') as SystemDataAccess,
  OBJECTPROPERTYEX(OBJECT_ID('dbo.DateStrToDate'), 'UserDataAccess') as UserDataAccess
А этот запрос что возвращает? Детерминированная UDF должна быть schemabinding вроде как
источник