|
|
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
Уважаемые знатоки!Помогите, пожалуйста, решить проблему. Я написал запрос на подсчет суммы в таблице MS SQL 7. Запрос выбирает данные из таблицы за 1 месяц.Это выглядит так: where (period between '07/01/02' and '08/01/02') Такой запрос работает примерно 20 секунд. Но т.к. мне нужен универсальный запрос, то я написал хранимую процедуру, в которую передаю эти две даты, т.е. запрос уже будет таким: where (period between @data1 and @data2) Но, что самое удивительное, такой запрос работает почти 1,5 минуты. Вопрос: В чем дело? Никакого существенного различия между запросами я не вижу. Помогите, пожалуйста. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2002, 15:45:56 |
|
||
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
а сколько записей в таблице? что-то 20 секунд многовато чтобы сумму посчитать.... и полные тексты запросов приведи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2002, 15:51:49 |
|
||
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
В запросе участвуют примерно 100000 записей. 1 вариант(время выполнения 26 секунд): Select 'ДГТС ','Абонентная плата','КВС', (select isnull(sum(p.Summa),0.00) from Client c , Pers_Account p , DEVICENUMBER d where d.Fine>10 and p.Number=d.Number and (c.Branch=1) and c.Client=p.Client and p.ServiceType=2 and (p.Period between '07/01/02' and '08/01/02')), (select isnull(sum(p.Summa),0.00) from Client c , Pers_Account p where c.Branch=1 and c.Client=p.Client and p.ServiceType=2 and (p.Period between '07/01/02' and '08/01/02')),0.00 2 вариант(время выполнения 2 минуты 46 секунд): declare @period1 datetime,@period2 datetime select @period1='07/01/02' select @period2=dateadd(month,1,@period1) Select 'ДГТС ','Абонентная плата','КВС', (select isnull(sum(p.Summa),0.00) from Client c , Pers_Account p , DEVICENUMBER d where d.Fine>10 and p.Number=d.Number and (c.Branch=1) and c.Client=p.Client and p.ServiceType=2 and (p.Period between @period1 and @period2)), (select isnull(sum(p.Summa),0.00) from Client c , Pers_Account p where c.Branch=1 and c.Client=p.Client and p.ServiceType=2 and (p.Period between @period1 and @period2)),0.00 В чем же разница между запросами? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2002, 16:09:46 |
|
||
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
Попробуй BETWEEN заменить на вот это: and (p.Period >= @period1 and p.Period <= @period2) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2002, 17:33:56 |
|
||
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
Я уже пробовал заменить between на конструкцию >= ...<= Не помогло. Знатоки! Не ужели вы не сталкивались с таким феноменом? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2002, 06:51:57 |
|
||
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
У тебя какой-то хитро сложный запрос. 20 секунд это очень много для суммы. попробуй упростить запрос. Добейся выполнения запроса за секунду. для 100 000 это можно сделать. попробуй сначала сделать выборку за период, а потом из этой выборки выбери по джругим критериям. Дело в том что план выполнения на запрос и на сохраненку строится по разному немногу.. поэтому могут быть проблеммы. Но в любом случае правь запрос. Лично мое мнение, мне кажется запрос у тебя неправильно составлен. вот и логика сервера "ошибается" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2002, 10:10:36 |
|
||
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
IMHO просто при построении плана выполнения т.к. для первого запроса диапазон дат известен планировщику, то он скорее всего использует какой-либо индекс, включающий себя поле p.Period Для второго же запроса, где используются переменные, планировщик не может определить заранее, что нужно использовать это индекс. Ведь переменная приобредет значение только при выполнении пакета. Проанализируйте планы выполнения обеих запросов. Если действительно в первом запросе используется Index Seek/Scan, а во втором - Table Scan, то можно принудить оптимизатор к использованию индекса с помощью WITH (INDEX(...)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2002, 10:16:39 |
|
||
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
И ещё проверь, какой тип у поля p.Period, сдаётся мне, что он не datetime. А что будет, если по человечески написать? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2002, 10:34:20 |
|
||
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
:)) Забавно, но пока никто (кроме Glory) ничего по существу не ответил. Запросы, конечно, ужасные, но вопрос-то не про это. То есть вопрос звучит не "Почему так долго?", а "Почему в 4 с лишним раза дольше?". Прикол в том, что у нас в аналогичной ситуации результаты были ровно обратные (то есть при использовании констант время выполнения запроса было существенно больше, чем при использовании переменных). В общем "темна вода во облацех"... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2002, 13:27:22 |
|
||
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
Уважаемые знатоки! Может я неправильно сформировал запрос. Но тогда другой вопрос: 1 запрос Select 'ДГТС ','Абонентная плата','КВС', (select isnull(sum(p.Summa),0.00) from Client c , Pers_Account p , DEVICENUMBER d where d.Fine>10 and p.Number=d.Number and (c.Branch=1) and c.Client=p.Client and p.ServiceType=2 and (p.Period between '07/01/02' and '08/01/02')) 2 запрос (select isnull(sum(p.Summa),0.00) from Client c , Pers_Account p , DEVICENUMBER d where d.Fine>10 and p.Number=d.Number and (c.Branch=1) and c.Client=p.Client and p.ServiceType=2 and (p.Period between '07/01/02' and '08/01/02')) Давайте абстрагируемся от индексов и всего прочего. Почему первый запрос работает 5 секунд, а второй 7 секунд. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2002, 13:40:33 |
|
||
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
А бог его знает. Так оптимизатор соптимизировал. Я в таких случаях сначала делаю sp_updateststs, просто так на всякий случай, а уж потом разбираюсь. Надо смотреть екзекушин план, так не понять. Можно попробовать всякие хинты к селекту использовать. Но смысл примерно такой - туповат оптимизатор. Правда, ещё существует вероятность, что вы, мягко говоря, не всю правду говорите. Ведь время выполнения запроса - величина непостоянная. Ну например, во время выполнения второго запроса был скачёк нагрузки на сервере. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2002, 14:14:21 |
|
||
|
Разница по времени выполнения двух идентичных запросов
|
|||
|---|---|---|---|
|
#18+
К знатокам себя не отношу и не буду рассуждать на тему возможных причин данного явления, однако сталкивался с подобной ситуацией - без хранимой процедуры работает намного (обычно в разы) быстрее, чем в оной. Проявлялось именно на типе datetime. Единственный вариант, который сработал, это замена переменных-параметров в запросе на локальные переменные, объявленные в теле процедуры. Например: create procedure abc @num int, @period1 datetime, @period2 datetime as declare @p1 datetime set @p1 = @period1 declare @p2 datetime set @p2 = @period2 /*далее остальной текст процедуры*/ --...where (period between @p1 and @p2) Буду рад, если поможет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.08.2002, 23:20:58 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32044693&tid=1820801]: |
0ms |
get settings: |
6ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
53ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
44ms |
get tp. blocked users: |
1ms |
| others: | 199ms |
| total: | 328ms |

| 0 / 0 |
