Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2002.07.22;
Скачать: [xml.tar.bz2];

Вниз

Время выполнения запроса   Найти похожие ветки 

 
KAA   (2002-06-28 18:00) [0]

Есть запрос, выполняется примерно секунду, может иногда две. Но если в WHERE сдлеать хотя бы проверку переменой на NOT NULL, запрос выполняется уже 10секунд. А если там будет проверка типа
((@UIDService=journal_service.UIDService) or (@UIDService IS NULL))
он уже выполняется 20 секуд, независимо от количества таких проверок.
Если добавить просто проверку какого либо поля базы, на время запроса не сказывается. Т.е. чем-то ему не нравятся переменные в области WHERE.
В чем может быть проблема?


 
KAA   (2002-06-28 18:00) [1]

Да, речь идет о MSSQL 2000


 
Shaman_Naydak   (2002-06-28 18:55) [2]

А какой смысл заранее посчитанное значение в запросе проверять на NULL ?


 
dimis   (2002-06-28 18:56) [3]

какой sql не важно
скорее всего запрос составнен не совсем грамотно
напиши его полностью


 
TSV   (2002-06-28 19:09) [4]

Есть такая буква в этом слове...
Допустим, вы пишите процедуру для многокритериального поиска. Причем некоторые (любые) параметры могут быть опущены при вызове (в процедуру они прийдут как NULL). Тогда в теле запроса нужно писать:
...
where (...)
and (@Param1 is NULL or Field1 = @Param1)
...

В случае символьных параметров этого можно избежать, указав перед запросом: set @Param1 = COALESCE(@Param1, "%")

Почему происходят тормоза, я не знаю. Скорее всего, это вопрос к разработчикам из MS. Что-то не так с оптимизатором...
А нам, простым смертным, остается по возможности избегать таких выражений в запросах, подставлять значения по умолчанию и т.д.

С уважением.


 
TSV   (2002-06-28 19:17) [5]

Кстати, в семерке то же самое...
И еще: когда писал про опущенные параметры, имел в виду вот что:

CREATE PROCEDURE dbo.FindXXX
@Param1 int = NULL
,@Param2 datetime = NULL
,@Param3 varchar(30) = NULL
AS BEGIN
...
...
END



 
KAA   (2002-06-28 19:40) [6]

>А какой смысл заранее посчитанное значение в запросе проверять на NULL ?

Я передаю параметры с хранимую процедуру, которые учавствуют в запросе.

>Почему происходят тормоза, я не знаю. Скорее всего, это вопрос к разработчикам из MS

Учитывая, что с MSSQL я работаю меньше года, подозреваю что это мой глюк.

>напиши его полностью
Выполняю


CREATE PROCEDURE JournalServiceSelect
@UIDService int = NULL,
@UIDBill int = NULL,
@UIDPayer int = NULL,
@UIDRecipient int = NULL,
@Pay int = NULL,
@Charge int = NULL,
@DTPayBegin datetime = NULL,
@DTPayEnd datetime = NULL,
@DTChargeBegin datetime = NULL,
@DTChargeEnd datetime = NULL,
@UIDManPay int = NULL,
@UIDManCharge int = NULL,
@UIDManClient int = NULL,
@Ordering int = NULL

AS

IF ((@Ordering IS NULL) or (@Ordering>0)) SET @Ordering=0
IF (@UIDService=0) SET @UIDService=NULL
IF (@UIDBill=0) SET @UIDBill=NULL
IF (@UIDPayer=0) SET @UIDPayer=NULL
IF (@UIDRecipient=0) SET @UIDRecipient=NULL
IF (@UIDManPay=0) SET @UIDManPay=NULL
IF (@UIDManCharge=0) SET @UIDManCharge=NULL
IF (@UIDManClient=0) SET @UIDManClient=NULL
IF (@Pay IS NULL) SET @Pay=0
IF (@Charge IS NULL) SET @Charge=0

IF @Ordering<=0 BEGIN
SELECT TOP 1000
journal_service.UID,
journal_service.UIDOwner,
journal_service.DTInsert,
journal_service.DTUpdate,
journal_service.UIDService,
journal_service.UIDBill,
list_service.Caption AS CaptionService,
list_unit.Caption AS CaptionUnit,
journal_service.Quantity,
journal_service.Lag,
journal_service.Discount,
journal_service.Taxrate,
journal_service.Caption,
journal_amount.UIDPayer AS UIDRecipient,
journal_amount.UIDRecipient AS UIDPayer,
journal_service.UIDManPay,
journal_service.UIDManCharge,
journal_service.UIDManClient,
journal_service.DTPay,
journal_service.DTCharge,
sum(journal_amount.Amount) AS SumCharge,
CASE WHEN (journal_service.DTPay IS NOT NULL) THEN sum(journal_amount.Amount)
ELSE NULL
END AS SumPay,
CASE WHEN (journal_service.DTPay IS NULL) THEN 1
ELSE 2
END AS Pay,
CASE WHEN (journal_service.DTCharge IS NULL) THEN 1
ELSE 2
END AS Charge
FROM
journal_service
LEFT OUTER JOIN list_service ON journal_service.UIDService = list_service.UID
LEFT OUTER JOIN list_unit ON list_service.UIDUnit = list_unit.UID
LEFT OUTER JOIN (SELECT DISTINCT UIDService, max(DTActual) AS MaxDate
FROM journal_service_taxrate
GROUP BY UIDService) AS max_date ON list_service.UID=max_date.UIDService
LEFT OUTER JOIN journal_service_taxrate ON ((max_date.UIDService=journal_service_taxrate.UIDService) and (max_date.MaxDate=journal_service_taxrate.DTActual))
LEFT OUTER JOIN bind_amount_service ON journal_service.UID=bind_amount_service.UIDJournalService
LEFT OUTER JOIN journal_amount ON bind_amount_service.UIDAmount=bind_amount_service.UID
WHERE
((journal_service.UIDPayer=journal_amount.UIDRecipient) or (bind_amount_service.UIDJournalService IS NULL)) and
((@UIDService=journal_service.UIDService) or (@UIDService IS NULL)) and
((@UIDBill=journal_service.UIDBill) or (@UIDBill IS NULL)) and
((@UIDManPay=journal_service.UIDManPay) or (@UIDManPay IS NULL)) and
((@UIDManCharge=journal_service.UIDManCharge) or (@UIDManCharge IS NULL)) and
((@UIDManClient=journal_service.UIDManClient) or (@UIDManClient IS NULL)) and
(((journal_service.DTPay IS NOT NULL) and (@Pay=2)) or
((journal_service.DTPay IS NULL) and (@Pay=1)) or
(@Pay=0)) and
(((journal_service.DTCharge IS NOT NULL) and (@Charge=2)) or
((journal_service.DTCharge IS NULL) and (@Charge=1)) or
(@Charge=0)) and
((@UIDPayer=journal_service.UIDPayer) or (@UIDPayer IS NULL)) --and
GROUP BY
journal_service.UID,
journal_service.UIDOwner,
journal_service.DTInsert,
journal_service.DTUpdate,
journal_service.UIDService,
journal_service.UIDBill,
list_service.Caption,
list_unit.Caption,
journal_service.Quantity,
journal_service.Lag,
journal_service.Discount,
journal_service.Taxrate,
journal_service.Caption,
journal_amount.UIDPayer,
journal_amount.UIDRecipient,
journal_service.UIDManPay,
journal_service.UIDManCharge,
journal_service.UIDManClient,
journal_service.DTPay,
journal_service.DTCharge
ORDER BY
journal_service.UID
END
GO


 
Shaman_Naydak   (2002-06-28 20:10) [7]

Вот что я могу посоветовать реально работающее:
Динамически строй свой запрос:
то есть заведи переменную типа varchar(4000) и в нее потихоньку суммируй по алгоритму:
IF @UIDPayer IS NOT NULL
SET @Str = @STR + and (@UIDPayer=journal_service.UIDPayer)
Это эквивалентно твоей конструкции
((@UIDPayer=journal_service.UIDPayer) or (@UIDPayer IS NULL))

А потом запустишь, как Exec(@Str)...


 
Shaman_Naydak   (2002-06-28 20:11) [8]

Блин, кавычки забыл в
NULL
SET @Str = @STR + "and (@UIDPayer=journal_service.UIDPayer)"


 
kaif   (2002-06-29 01:07) [9]

LEFT OUTER JOIN - не лучшая задача для оптимизаторов запросов.


 
Polevi   (2002-06-29 10:47) [10]

2KAA ©
Присоединяюсь к Shaman_Naydak ©
Только вместо Exec используй sp_executesql
В свое время я здорово ускорил свои отчеты таким способом



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2002.07.22;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.006 c
14-70869
Странный Прохожий
2002-06-24 12:56
2002.07.22
Кактусы


1-70722
Ivan61
2002-07-10 23:46
2002.07.22
Калькулятор!?


14-70919
MJH
2002-06-25 06:04
2002.07.22
Кто нить уже пытался WMA ломать?


14-70883
Bishop
2002-06-25 05:58
2002.07.22
Где можно скачать Delphi Builder?


1-70715
novice_al
2002-07-11 14:58
2002.07.22
вопрос дилетанта, но необходим





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский