Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 MS SQL запрос  [new]
Valerii
Member

Откуда:
Сообщений: 749
Народ,
Помогите понять одну вещь.
Есть запрос, который храниться в ХП и который возвращает набор данных.
Так вот, этот набор может содержать NULL значения по определенному полю, которое иногда нужно видеть, а по умолчанию записей с значением этого поля равным NULL не должнл быть.
Если полный набор данных с NULL записями содержит к примеру 15 тыс записей, а без низх - 5 тыс, и если вставить
where ChkField IS NOT NULL то запросу нужно в 5 раз больше времени на его доставку клиенту. Подскажите как должна выглядеть процедура, чтобы по логике запрос отрабатывался в 3 раза быстрее при исключении NULL значений в записях.
Всем спасибо.
то
16 сен 11, 13:22    [11287270]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
set run three times faster on
16 сен 11, 13:24    [11287298]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Valerii
Member

Откуда:
Сообщений: 749
Гавриленко Сергей Алексеевич,

Это как?
16 сен 11, 13:25    [11287310]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
Valerii
Подскажите как должна выглядеть процедура, чтобы по логике запрос отрабатывался в 3 раза быстрее при исключении NULL значений в записях.

Т.е. нужно
- угадать ваш текущий запрос
- оптимизировать его
- и предложить вам
16 сен 11, 13:25    [11287315]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Valerii
Member

Откуда:
Сообщений: 749
Гавриленко Сергей Алексеевич,

MS SQL 2000
16 сен 11, 13:27    [11287331]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
плановый показыватель
Guest
Valerii,

смотрите как план запроса с фильтром/без фильтра меняется
16 сен 11, 13:28    [11287347]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Valerii
Member

Откуда:
Сообщений: 749
Glory,

Он большой, одним селектом все делается..
  
CREATE PROCEDURE dbo.GMovementBetween_NEW
@pBeforeStDate DateTime, @pBeforeEndDate DateTime, @pBranch Numeric(4) = 0, @pNotNull Numeric(1) = NULL
AS
/*vLst_goods.id_Maincategory, vLst_goods.Color, */
SELECT * FROM
(SELECT vLst_goods.id, vLst_goods.ean13, vLst_goods.articul,
vLst_goods.Text, vLst_goods.id_Maincategory, vLst_goods.Color, vLst_Goods.Id_category,
ISNULL(detail_before.Prihod,0.00) AS Prihod ,
ISNULL(detail_before.IntPrihod,0.00) AS IntPrihod ,
ISNULL(detail_before.Rashod,0.00) AS Rashod ,
ISNULL(detail_before.IntRashod,0.00) AS IntRashod ,
ISNULL(detail_before.Returned,0.00) AS Returned ,
ISNULL(sls_before.totalsales,0.00) AS totalsales ,
ISNULL(detail.Prihod_Between,0.00) AS Prihod_Between ,
ISNULL(detail.IntPrihod_Between,0.00) AS IntPrihod_Between ,
ISNULL(detail.Rashod_Between,0.00) AS Rashod_Between ,
ISNULL(detail.IntRashod_Between,0.00) AS IntRashod_Between ,
ISNULL(detail.Returned_Between,0.00) AS Returned_Between ,
ISNULL(sls.totalsales_Between,0.00) AS totalsales_Between ,
ISNULL(avgprice.MiddlePrice,0.00) AS MiddlePrice ,
avgprice.MiddlePrice AS CheckNull
FROM vLst_goods
LEFT JOIN
(SELECT ino_before.id_goods, SUM(ino_before.xPrihod) AS Prihod,
SUM(ino_before.xIntPrihod) AS IntPrihod,
SUM(ino_before.xRashod) AS Rashod,
SUM(ino_before.xIntRashod) AS IntRashod,
SUM(ino_before.xReturned) AS Returned
FROM
(
SELECT id_goods, xPrihod = CASE When operation = 1 AND TypeDoc = '0' THEN quantity ELSE 0.00 END,
xIntPrihod = CASE When operation = 1 AND TypeDoc = 'int.' THEN quantity ELSE 0.00 END,
xReturned = CASE WHEN operation = 1 AND TypeDoc = 'ret.' THEN quantity ELSE 0.00 END,
xRashod = CASE WHEN operation = 2 THEN quantity ELSE 0.00 END,
xIntRashod = CASE WHEN operation = 3 THEN quantity ELSE 0.00 END
from inout WHERE (branch = @pBranch OR @pBranch = 0) AND data < @pBeforeStDate
) ino_before
GROUP BY ino_before.id_goods) detail_before
ON vLst_goods.id = detail_Before.id_goods
LEFT JOIN
(SELECT id_goods, SUM(quantity) AS totalSales FROM SALES
WHERE (branch = @pBranch OR @pBranch = 0) AND convert(VARCHAR(10), data, 112) < @pBeforeStDate
GROUP BY id_goods) Sls_before
on vLst_goods.id = sls_before.id_goods
LEFT JOIN
(SELECT ino.id_goods, SUM(ino.xPrihod) AS Prihod_Between,
SUM(ino.xIntPrihod) AS IntPrihod_between,
SUM(ino.xRashod) AS Rashod_Between,
SUM(ino.xIntRashod) AS IntRashod_Between,
SUM(ino.xReturned) AS Returned_Between
FROM
(
SELECT id_goods, xPrihod = CASE When operation = 1 AND TypeDoc = '0' THEN quantity ELSE 0.00 END,
xIntPrihod = CASE When operation = 1 AND TypeDoc = 'int.' THEN quantity ELSE 0.00 END,
xReturned = CASE WHEN operation = 1 AND TypeDoc = 'ret.' THEN quantity ELSE 0.00 END,
xRashod = CASE operation When 2 THEN quantity ELSE 0 END,
xIntRashod = CASE operation When 3 THEN quantity ELSE 0 END
from inout WHERE (branch = @pBranch OR @pBranch = 0) AND data Between @pBeforeStDate AND @pBeforeEndDate
) ino
GROUP BY ino.id_goods
) detail
on vLst_goods.id = detail.id_goods
LEFT JOIN
(SELECT id_goods, SUM(quantity) AS totalSales_Between FROM SALES
WHERE (branch = @pBranch OR @pBranch = 0) AND convert(VARCHAR(10), data, 112) Between @pBeforeStDate AND @pBeforeEndDate
GROUP BY id_goods) Sls
on vLst_goods.id = sls.id_goods
LEFT JOIN
(SELECT ID_GOODS,SUM(Quantity * salePrice) / SUM(Quantity) AS MiddlePrice
FROM INOUT
WHERE (Operation = 1 OR operation = 3) AND (branch = @pBranch OR @pBranch = 0)
GROUP BY ID_GOODS) avgprice
on vLst_goods.id = avgprice.id_goods
) finalResult
WHERE finalResult.CheckNull IS NOT NULL
ORDER BY finalResult.id
GO

16 сен 11, 13:30    [11287365]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
глазовылуп сиамский
Guest
Valerii
очуметь мл

и подтупливает? странно, так и не скажешь.
16 сен 11, 13:31    [11287378]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2423
Valerii,

вынести в наружный WHERE вот это
id in (SELECT * FROM inout WHERE (Operation = 1 OR operation = 3) AND (branch = @pBranch OR @pBranch = 0))
вместо
finalResult.CheckNull IS NOT NULL

может поможет, но не факт, без плана и структуры индексов это на кофейной гуще как говорится:)
16 сен 11, 13:39    [11287450]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
locky
Member

Откуда: Харьков, Украина
Сообщений: 62034
избавиться от convert(VARCHAR(10), data, 112)
смержить подзапросы из SALES
смержить подзапросы из INOUT
16 сен 11, 13:54    [11287614]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Valerii
Member

Откуда:
Сообщений: 749
locky,

Проблема не в этом
если убрать WHERE .... все летает, как только вставляю WHERE - все - жопа..
16 сен 11, 14:02    [11287723]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Valerii
locky,

Проблема не в этом
если убрать WHERE .... все летает, как только вставляю WHERE - все - жопа..
Не ставьте where и не будет проблем, тогда. Все просто.
16 сен 11, 14:04    [11287745]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
Valerii
если убрать WHERE .... все летает, как только вставляю WHERE - все - жопа..

Потому что вы считаете, что этот WHERE сервер почему то должен выполнять последним шагом
16 сен 11, 14:05    [11287752]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
locky
Member

Откуда: Харьков, Украина
Сообщений: 62034
Valerii
locky,

Проблема не в этом
если убрать WHERE .... все летает, как только вставляю WHERE - все - жопа..

Ну, не в этом так не в этом
моё дело - намекнуть.
16 сен 11, 14:08    [11287784]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Valerii
Member

Откуда:
Сообщений: 749
Glory,

А разве не так? Сначала отрабатвается выборка на сервере и как набор даннх сформирован - передаются данные клиентскому приложению, или я то-то не так понимаю?
16 сен 11, 15:24    [11288717]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
Valerii
Glory,

А разве не так? Сначала отрабатвается выборка на сервере и как набор даннх сформирован - передаются данные клиентскому приложению, или я то-то не так понимаю?

А какое отношение возврат данных клиенту имеет к порядку вычислений при выполнении запроса ?
я про другое говорил
16 сен 11, 15:28    [11288756]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Valerii
Glory,

А разве не так? Сначала отрабатвается выборка на сервере и как набор даннх сформирован - передаются данные клиентскому приложению, или я то-то не так понимаю?
Расскажите ка, каким образом вы померяли время отрабатывания выборки на сервере, время передачи данных клиентскому приложению, да еще и потом сделали вывод, что оказвается, именно время передачи увеличилось в три раза?
16 сен 11, 15:32    [11288801]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Valerii
Member

Откуда:
Сообщений: 749
Гавриленко Сергей Алексеевич,

С клинтского приложения включил отметку времени запуска, на сервере через Profiler просмотрел время запуска процедуры,
отсюда и оттолкнулся..
16 сен 11, 17:06    [11289732]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Valerii
Гавриленко Сергей Алексеевич,

С клинтского приложения включил отметку времени запуска, на сервере через Profiler просмотрел время запуска процедуры,
отсюда и оттолкнулся..
И как из двух времен запуска вычислить время окончания обработки записей сервером?
16 сен 11, 17:08    [11289749]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
darthVLAD
Member

Откуда: Київ
Сообщений: 293
  
....
avgprice.MiddlePrice AS CheckNull
....
LEFT JOIN
(SELECT ID_GOODS,SUM(Quantity * salePrice) / SUM(Quantity) AS MiddlePrice
FROM INOUT
WHERE (Operation = 1 OR operation = 3) AND (branch = @pBranch OR @pBranch = 0)
GROUP BY ID_GOODS) avgprice
on vLst_goods.id = avgprice.id_goods
) finalResult
WHERE finalResult.CheckNull IS NOT NULL
....

1) Если там нет необходимости использовать LEFT JOIN , то его лучше заменить на иннер джоин
2) отлавливать возможные значения NULL в Quantity или salePrice

тогда отпадёт необходимость в WHERE finalResult.CheckNull IS NOT NULL
16 сен 11, 17:47    [11290100]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Valerii
Member

Откуда:
Сообщений: 749
darthVLAD,

Нет, логика такова что нужно просчитать все движения товара за весь период, включая до, текущий и просчитать его остатки и уже по тем товарам которые не имели никакого движения - имп проставляется этот признак и его или показываем или отфильтровываем. Но мне непонятно почему так заработал селект коряво в этой ситуации. селект не такой уж и сложный и тяжелый, тупые операции суммирования за определенные периоды (сами по себе выполнившиеся первый раз сервер остальные все должен по описаниям просчитывать в разы быстрее) и JOIN-а...
16 сен 11, 18:50    [11290486]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
Valerii
Но мне непонятно почему так заработал селект коряво в этой ситуации. селект не такой уж и сложный и тяжелый, тупые операции суммирования за определенные периоды (сами по себе выполнившиеся первый раз сервер остальные все должен по описаниям просчитывать в разы быстрее) и JOIN-а...

И что вам мешает выяснить причины этого на основе плана выполнения ?
Вы наверное думаете, что запрос всегда выполняется в том порядке, в котором вы его написали ?
16 сен 11, 18:54    [11290499]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31960
Valerii,

Замените последний LEFT JOIN на JOIN
16 сен 11, 18:58    [11290508]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
darthVLAD
Member

Откуда: Київ
Сообщений: 293
Valerii
darthVLAD,

Нет, логика такова что нужно просчитать все движения товара за весь период, включая до, текущий и просчитать его остатки и уже по тем товарам которые не имели никакого движения - имп проставляется этот признак и его или показываем или отфильтровываем. Но мне непонятно почему так заработал селект коряво в этой ситуации. селект не такой уж и сложный и тяжелый, тупые операции суммирования за определенные периоды (сами по себе выполнившиеся первый раз сервер остальные все должен по описаниям просчитывать в разы быстрее) и JOIN-а...

т.е. вы сначала выводите заведомо ненужные значения,а потом отсеиваете их?
насколько я вижу логику работы данного запроса, то тут left join + where = inner join (при условии, что Quantity и salePrice не принимают значения null)
16 сен 11, 23:55    [11291532]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31960
darthVLAD
т.е. вы сначала выводите заведомо ненужные значения,а потом отсеиваете их?
насколько я вижу логику работы данного запроса, то тут left join + where = inner join (при условии, что Quantity и salePrice не принимают значения null)
Даже без этого условия реально получается inner join

Просто код писали по принципу - добавим что-нибуть и посмотрим, правильный ли получится результат. Никто из программистов запрос не читал :-)
17 сен 11, 10:39    [11291940]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить