Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Не понятное поведение mssql  [new]
Kasper 3000
Member

Откуда:
Сообщений: 9
Здравствуйте.

Оборудование:
Мощный сервер с большим кол-вом памяти и sas винтами. (проблема точно не в медленном железе)
ПО:
MSSQL 2008

Есть запрос:
SELECT     dbo.fGetDocInfo(d.dID) as docinfo
FROM     Docs AS d
            INNER JOIN DocTypes AS dt ON (d.dtID = dt.dtID) AND (dt.dtTag in('ACTR','ACTP'))
            LEFT OUTER JOIN Firms AS ffrom ON ffrom.fID = d.fFromID
where (d.dDocDate >='01.08.2015' AND d.dDocDate <= '31.08.2015')  
and dbo.fCheckDoc(d.dID)=0


Функция fCheckDoc :
+

Функция проверяет принадлежность товаров в документе к группам товаров
CREATE FUNCTION [dbo].[fCheckDoc]
(
 @dId uniqueidentifier     -- Идентификатор документа
)
RETURNS int
AS
BEGIN

 if EXISTS(
    select *
    from DocGoods dg
    inner join GoodsGoodsGroups ggg on ggg.gID=dg.gID
    where dg.dID=@dId
    and
    (ggg.ggID in (Список идентификаторов групп))
  begin
    return 1
  end

    return 0

END


Возникла следующая проблема:
Данный запрос формируется порядка 6 мин, при этом запрос:
SELECT     dbo.fGetDocInfo(d.dID) as docinfo,dbo.fCheckDoc(d.dID)
FROM     Docs AS d
            INNER JOIN DocTypes AS dt ON (d.dtID = dt.dtID) AND (dt.dtTag in('ACTR','ACTP'))
            LEFT OUTER JOIN Firms AS ffrom ON ffrom.fID = d.fFromID
where (d.dDocDate >='01.08.2015' AND d.dDocDate <= '31.08.2015')  

формируется мгновенно.

Самое не понятно, если поставить период дат в котором нет
документов, тоесть проверка dbo.fCheckDoc не должная выполнятся,
время выполнения не меняется (несколько минут)

Где можно глянуть причину такого поведения, план запроса полезной информации не даёт,
по форуму даже не знаю какую тему искать, т.к. не могу понять, хоть приблизительно, что искать?
Буду благодарен за указания направления в котором нужно рыть.
27 авг 15, 11:19    [18075116]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
Maxx_UA
Guest
пацдравляю - классические грабли
1. Уберите вашу скалярку (нахфиг)
2. Зачем лефт джойн в запросе - если он реально нигде не используеться ?
27 авг 15, 11:30    [18075202]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
Kasper 3000
Member

Откуда:
Сообщений: 9
Maxx_UA
пацдравляю - классические грабли
1. Уберите вашу скалярку (нахфиг)

Не могу я её убрать, она используется в большом кол-ве отчетов,
и менять их все при изменении списка групп нет желания.

В других запросах эта функция отрабатывает быстро, проблема именно в этом конкретном запросе.
Я не пойму как мне найти где затык. Запускал на разных клиентах FastReport, EMS, Studio результат один.


Maxx_UA
2. Зачем лефт джойн в запросе - если он реально нигде не используеться ?


Тут согласен, не используется, но это не является причиной проблемы.
27 авг 15, 11:44    [18075339]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
churupaha
Member

Откуда: Краснодар
Сообщений: 1015
Kasper 3000,

может краюху плана актуального мельком покажете?
27 авг 15, 11:49    [18075388]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
vanezy
Member

Откуда: Ekaterinburg->Moscow->Frankfurt
Сообщений: 122
Kasper 3000,

Переписать скалярку на table inline никак?
27 авг 15, 11:54    [18075436]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
Kasper 3000
В других запросах эта функция отрабатывает быстро, проблема именно в этом конкретном запросе.
Проблема в этой функции. Потому что используется в фильтре.

Сделайте инлайновый вариант:
CREATE FUNCTION dbo.fCheckDoc_inline
(
 @dId uniqueidentifier     -- Идентификатор документа
)
RETURNS table as
AS
return (
 select 1 as result
 where
  EXISTS(
    select *
    from DocGoods dg
    inner join GoodsGoodsGroups ggg on ggg.gID=dg.gID
    where dg.dID=@dId
    and
    (ggg.ggID in (Список идентификаторов групп)));

Перепишите скалярную:
ALTER FUNCTION dbo.fCheckDoc
(
 @dId uniqueidentifier     -- Идентификатор документа
)
RETURNS int
AS
BEGIN

 if EXISTS(
    select *
    from dbo.fCheckDoc_inline(@dId))
  begin
    return 1
  end

    return 0

END

Перепишите запрос:
SELECT     dbo.fGetDocInfo(d.dID) as docinfo
FROM     Docs AS d
            INNER JOIN DocTypes AS dt ON (d.dtID = dt.dtID) AND (dt.dtTag in('ACTR','ACTP'))
            LEFT OUTER JOIN Firms AS ffrom ON ffrom.fID = d.fFromID
where (d.dDocDate >='01.08.2015' AND d.dDocDate <= '31.08.2015')  
and not exists(select * from dbo.fCheckDoc_inline(d.dId))
27 авг 15, 12:36    [18075763]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
Насколько я знаю, 31-го месяца не бывает.
Почему бы не записывать даты нормально?
27 авг 15, 14:07    [18076568]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31439
Kasper 3000
Данный запрос формируется порядка 6 мин, при этом запрос:
...
формируется мгновенно.
Потому что функция вызывается для каждой строки, это очень медленно. Нужно это учитывать при проектировании модели данных.

Kasper 3000
Самое не понятно, если поставить период дат в котором нет
документов, тоесть проверка dbo.fCheckDoc не должная выполнятся,
время выполнения не меняется (несколько минут)
Ответ в плане выполнения. Может, функция вызывается для каждой строки, до наложения фильтра по датам? Это тоже нужно учитывать при проектировании модели данных и написании запросов.
Kasper 3000
по форуму даже не знаю какую тему искать, т.к. не могу понять, хоть приблизительно, что искать?
Искать по словам профайлер, трейс, планы выполнения, функция медленно работает.

Kasper 3000
Не могу я её убрать, она используется в большом кол-ве отчетов,
и менять их все при изменении списка групп нет желания.
Странно, что этого не заметили раньше (раз много отчётов); странно, что в проекте не было человека с опытом работы с сиквелом, который знал, что всё так должно, и так будет работать, когда принимал решение об использовании функций таким образом.
Kasper 3000
Запускал на разных клиентах FastReport, EMS, Studio результат один.
Улыбнуло, всё равно что "пробовал писать другим почерком" :-)
27 авг 15, 14:25    [18076668]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Kasper 3000
Maxx_UA
пацдравляю - классические грабли
1. Уберите вашу скалярку (нахфиг)

Не могу я её убрать, она используется в большом кол-ве отчетов,
и менять их все при изменении списка групп нет желания.
Лень вас погубит.


SELECT     dbo.fGetDocInfo(d.dID) as docinfo,dbo.fCheckDoc(d.dID) as CheckDoc
INTO #T
FROM     Docs AS d
            INNER JOIN DocTypes AS dt ON (d.dtID = dt.dtID) AND (dt.dtTag in('ACTR','ACTP'))
            LEFT OUTER JOIN Firms AS ffrom ON ffrom.fID = d.fFromID
where (d.dDocDate >='01.08.2015' AND d.dDocDate <= '31.08.2015')

SELECT docinfo
FROM #T
WHERE CheckDoc = 0 
27 авг 15, 22:34    [18078648]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
Kasper 3000
Member

Откуда:
Сообщений: 9
churupaha
Kasper 3000,

может краюху плана актуального мельком покажете?


Общий план.

К сообщению приложен файл. Размер - 72Kb
28 авг 15, 07:51    [18079121]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
Kasper 3000
Member

Откуда:
Сообщений: 9
Спасибо за подробное объяснение с примерами. Пошел переделывать.
28 авг 15, 07:55    [18079127]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31439
Kasper 3000
Общий план.
Вообще по плану записи фильтруются по условию диапазона дат, а потом вызывается функция для каждой записи. То есть проблема просто в самой высокой стоимости вызовов функции.

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

ИМХО поможет только полноценное переписывание на INLINE (не так, как написал invm, а что бы вообще скалярной функции не было).
28 авг 15, 09:24    [18079404]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
человек_ниоткуда
Guest
Вот прямо один в один проблема у нас. Внезапные зависоны в запросах, где используются скаларные функции с запросами внутри. Нахфиг скалярку бро... Нахфиг. И ещё рекомендуется публичная порка тех, кто так пишет.

Но я своих бандерлогов заставляю такое переписывать на VIEW, чтоб в запросах всовывать так:
 
... exists (select  * from GoodsGoodsGroupsCut_vw v where v.gID =doc.gID)


Вы имейте ввиду что в SQL, инкапсуляция, это тернистый путь причём через бесконечное минное поле. Лучше пользоваться инструментами генерации кода, например T4.
28 авг 15, 10:28    [18079724]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
Kasper 3000
Member

Откуда:
Сообщений: 9
Функцию переписал.
Все прекрасно работает.
Всем спасибо за помощь.
28 авг 15, 10:57    [18079927]     Ответить | Цитировать Сообщить модератору
 Re: Не понятное поведение mssql  [new]
saszay
Member

Откуда: Тольятти
Сообщений: 454
Kasper 3000
Функцию переписал.
Все прекрасно работает.
Всем спасибо за помощь.


А можно узнать: как переписали?
10 ноя 15, 08:50    [18393084]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить