Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Очень популярная тема (более 25 ответов) Медленное получение значения периодического реквизита (число прочтений - 10529 )
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Медленное получение значения периодического реквизита
07. Декабря 2009 :: 09:55
Печать  
Сравниваю производительность одинаковых баз на двух разных серваках. Один сервак гораздо более мощный (и дисковая подсистема, и оперативная память, и проц). И практически на всех операторах это заметно: быстрее выполняются запросы, быстрее выводятся результаты запроса в отчет и т.п.

Единственно, что никак не могу понять, так это то, что на более мощном серваке дико тормозит оператор получения периодического реквизита, типа Валюта.Курс.Получить(Дата).

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

Так вот на 300 вызовах на более мощном сервере наблюдается общее замедление в 24 раза. Из-за чего такое может быть?
  
Наверх
 
IP записан
 
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Re: Медленное получение значения периодического реквизита
Ответ #1 - 07. Декабря 2009 :: 09:56
Печать  
Ну и соотвественно хотелось бы это как-то ускорить.
Но в первую очередь  определить причины нынешней ситуации
  
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3051
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #2 - 07. Декабря 2009 :: 10:05
Печать  
попробуй переиндексировать _1sconst
  

1&&2&&3
Наверх
 
IP записан
 
Злоп
Senior Member
****
Отсутствует


Ябба!

Сообщений: 317
Местоположение: г.Москва
Зарегистрирован: 14. Августа 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #3 - 07. Декабря 2009 :: 23:34
Печать  
Если пользоваться штатными возможностями, то использование для доступа к периодическим згначениям через
Пер = СоздатьОбъект("Периодический") - позволяет добиться ускорения примерно 25%
  
Наверх
www  
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #4 - 09. Декабря 2009 :: 07:29
Печать  
Neo писал(а) 07. Декабря 2009 :: 09:55:
Сравниваю производительность одинаковых баз на двух разных серваках. Один сервак гораздо более мощный (и дисковая подсистема, и оперативная память, и проц). И практически на всех операторах это заметно: быстрее выполняются запросы, быстрее выводятся результаты запроса в отчет и т.п.

Единственно, что никак не могу понять, так это то, что на более мощном серваке дико тормозит оператор получения периодического реквизита, типа Валюта.Курс.Получить(Дата).

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

Так вот на 300 вызовах на более мощном сервере наблюдается общее замедление в 24 раза. Из-за чего такое может быть?

Приведи более конкретный пример.
Я всегда использую ИспользоватьДату()
Кстати не рекомендуется смешивать Получить и использоватьДату.
Может быть у тебя именно этот случай?
  
Наверх
 
IP записан
 
elkpro
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 145
Зарегистрирован: 19. Мая 2006
Re: Медленное получение значения периодического реквизита
Ответ #5 - 09. Декабря 2009 :: 15:39
Печать  
У нас на базе зачастую наблюдается торможение при обращении к курсу валюты.

Через профайлер видно, что выполняется такой запрос
exec sp_executesql N'Select * from _1SCONST(NOLOCK) where ID=@P1 and OBJID=@P2 and DATE<=@P3 order by ID DESC, OBJID DESC, DATE DESC, TIME DESC, DOCID DESC, N'@P1 int,@P2 varchar(9),@P3 datetime', 92, '     2   ', 'Dec  9 2009 12:00:00:000AM'
и генерирует READS - 69993 и DURATION - 593
что видно, что зашкаливает.

Посмотрев план запроса - можно увидеть, что он сканирует таблицу констант и вытаскивает оттуда порядка 2800 строк.
Реиндексация не помогала. Помогло обновление статистики. Сейчас у меня статистика обновляется каждый день, т.к. размер базы уже порядка 65 Gb. В справочнике _1sconst сейчас порядка 2 200 000 записей.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #6 - 10. Декабря 2009 :: 06:58
Печать  
Только что проверил три разных метода
Код
Выбрать все
Процедура Сформировать1()
	Спр1 = СоздатьОбъект("Справочник.Валюты");
	Спр1.ИспользоватьДату(Дата1);
	Спр1.НайтиЭлемент(Вал1);
	Зн1 = Спр1.Текущ_курс;
	Сообщить("метод1 на дату = " + Дата1 + " курс = " + Зн1);
КонецПроцедуры

Процедура Сформировать2()
	Спр1 = СоздатьОбъект("Справочник.Валюты");
	Спр1.НайтиЭлемент(Вал1);
	Зн1 = Спр1.Текущ_курс.Получить(Дата1);
	Сообщить("метод2 на дату = " + Дата1 + " курс = " + Зн1);
КонецПроцедуры

Процедура Сформировать3()
	Спр1 = СоздатьОбъект("Справочник.Валюты");
	Спр1.НайтиЭлемент(Вал1);
	ТекЗапись=Спр1.ТекущийЭлемент();
	ПерКурс=СоздатьОбъект("Периодический");
	ПерКурс.ИспользоватьОбъект("Текущ_курс",ТекЗапись);
	Зн1 = ПерКурс.ЗначениеНаДату(Дата1);
	Сообщить("метод3 на дату = " + Дата1 + " курс = " + Зн1);
КонецПроцедуры
 


Все генерируют один и тот же запрос к базе данных

Код
Выбрать все
exec sp_executesql N'Select * from _1SCONST(NOLOCK)
where ID=@P1 and OBJID=@P2 and DATE<=@P3
order by ID DESC, OBJID DESC, DATE DESC, TIME DESC, DOCID DESC'
, N'@P1 int,@P2 varchar(9),@P3 datetime', 92, '     2   ', 'Oct  1 2009 12:00:00:000AM'
 


Недостатки этого запроса
1. Зачем возвращать все значения( а если там миллион строк) меня интересует только самая последняя  дата ( первая в выборке) надо всего лишь поставить  top 1
2. Зачем нужны order by ID DESC, OBJID DESC ведь id OBJID
не изменяются - лишняя нагрузка на sql
3. Если значения не меняются документами  тогда достаточно будет только сортировки  DATE

Вывод Чтобы ускорить получение периодич значения на дату
надо написать свой прямой запрос.

Если значение не меняется документами :
Select top 1 * from _1SCONST(NOLOCK)
where ID=@P1 and OBJID=@P2 and DATE<=@P3
order by DATE DESC


Если значение  меняется документами :
Select top 1 * from _1SCONST(NOLOCK)
where ID=@P1 and OBJID=@P2 and DATE<=@P3
order by DATE DESC, TIME DESC, DOCID DESC


Еще больше ускорить можно если эти новые запросы оформить как хранимые процедуры.

  
Наверх
 
IP записан
 
elkpro
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 145
Зарегистрирован: 19. Мая 2006
Re: Медленное получение значения периодического реквизита
Ответ #7 - 10. Декабря 2009 :: 07:11
Печать  
По поводу сортировки - ты не прав. 1С использует правильную конструкцию, т.к. только в этом случае идет точное попадание в индекс IDD
#----Indexes------
# Name                           |Descr         |Unique|Indexed fields                                              |Type      
I=PK__1SCONST                    |              |1     |ROW_ID                                                      |1         
I=IDD                            |              |1     |ID,OBJID,DATE,TIME,DOCID,ROW_ID                             |0         
I=DOC                            |              |1     |DOCID,ACTNO,ROW_ID                                          |0   


Я в базе переделал стандартную функцию получения курсов валют через параметрезированный запрос и  убрал в программе везде обращения напрямую типа Валюта.Курс.Получить() на глПолучитьКурс(Валюта,Дата). Это решило данную проблему и скорость существенно возросла.
У нас комплексная база и документ переоценка валют проводился порядка 40 мин. После вышеупомянутой замены стал проводится 5 мин.
Но таким образом нельзя решить проблему в Операциях, когда 1С каким-то своим способом обращается к константам для обновления текущего курса валюты в проводках.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #8 - 10. Декабря 2009 :: 07:17
Печать  
elkpro писал(а) 10. Декабря 2009 :: 07:11:
По поводу сортировки - ты не прав. 1С использует правильную конструкцию, т.к. только в этом случае идет точное попадание в индекс IDD
#----Indexes------
# Name                           |Descr         |Unique|Indexed fields                                              |Type      
I=PK__1SCONST                    |              |1     |ROW_ID                                                      |1          
I=IDD                            |              |1     |ID,OBJID,DATE,TIME,DOCID,ROW_ID                             |0          
I=DOC                            |              |1     |DOCID,ACTNO,ROW_ID                                          |0  


Я в базе переделал стандартную функцию получения курсов валют через параметрезированный запрос и  убрал в программе везде обращения напрямую типа Валюта.Курс.Получить() на глПолучитьКурс(Валюта,Дата). Это решило данную проблему и скорость существенно возросла.
У нас комплексная база и документ переоценка валют проводился порядка 40 мин. После вышеупомянутой замены стал проводится 5 мин.
Но таким образом нельзя решить проблему в Операциях, когда 1С каким-то своим способом обращается к константам для обновления текущего курса валюты в проводках.

И в чем я не прав. Индекс sql и сам подберет какой нужно ( а
если надо можно и самому его указать индекс) а дальше при сортировке
либо sql сервер будет делать не думая и сортировать все заданные поля
либо проанализировав ситуацию отбросит первые лишние сортировки,
но все равно sql сервер на это потратит свое время.
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #9 - 10. Декабря 2009 :: 07:42
Печать  
При попадании в индекс сортировки просто не будет.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
elkpro
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 145
Зарегистрирован: 19. Мая 2006
Re: Медленное получение значения периодического реквизита
Ответ #10 - 10. Декабря 2009 :: 07:42
Печать  
Нет в таблице индекса для поля DATE, которое сервер бы взял и использовал.
При этом при выполнении запроса не тратится время на нахождение данных в индексе, а потом на сортировку данных в таблице. SQL это сделает за один проход, т.к. в индексе перечислены все поля и эти данные он вытащит из индекса без обращений к таблице в уже упорядоченном варианте как указано в запросе.
Чего рассказывать теорию, когда ты это можешь взять и проверить на практике и посмотри что покажет план исполнения.
Сейчас при тормозном варианте используется Clustered Index Scan. В идеале должен использовать Index Seek  - idd.


  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #11 - 10. Декабря 2009 :: 08:03
Печать  
Что выберет sql еще зависит и от данных и от статистики
только что проверил

Select * from _1SCONST(NOLOCK)
where ID=92 and OBJID='     2   '
and DATE<='Oct  1 2009 12:00:00:000AM'
order by ID DESC, OBJID DESC, DATE DESC, TIME DESC, DOCID DESC


Select * from _1SCONST(NOLOCK)
where ID=92 and OBJID='     2   '
and DATE<='Oct  1 2009 12:00:00:000AM'
order by DATE DESC

Для обоих запросов sql выбрал cluster index scan ( строк в выборке 163 )
  
Наверх
 
IP записан
 
elkpro
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 145
Зарегистрирован: 19. Мая 2006
Re: Медленное получение значения периодического реквизита
Ответ #12 - 10. Декабря 2009 :: 08:19
Печать  
Я про индексирование и статистику уже писал.
В моем случае, когда вытаскиваются периодические значения на Май 2008, то он всегда использует Clustered Index Scan. Если я меняю дату на текущее число - тогда использует Index Seek - IDD.
  
Наверх
 
IP записан
 
elkpro
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 145
Зарегистрирован: 19. Мая 2006
Re: Медленное получение значения периодического реквизита
Ответ #13 - 10. Декабря 2009 :: 08:23
Печать  
У меня собственно сделан такой запрос

Это при загрузке 1С
ТекстЗапроса="
     |DECLARE @пВалюта char(9), @пНаДату datetime
     |SET @пНаДату = ?
     |SET @пВалюта = ?
     |SELECT CASE WHEN Кратность=0 THEN Курс ELSE Курс/Кратность END Курс
     |FROM (
     |SELECT $ПоследнееЗначение.Валюты.Курс(@пВалюта,@пНаДату) Курс
     |       , COALESCE($ПоследнееЗначение.Валюты.Кратность(@пВалюта,@пНаДату),1) Кратность ) Курсы
     |";
     
     глЗапросПоВалютам=СоздатьОбъект("ODBCRecordSet");
     глЗапросПоВалютам.Подготовить(ТекстЗапроса);
     глЗапросПоВалютам.ДобПараметр(1,10,17,0);
     глЗапросПоВалютам.ДобПараметр(1,14,9,0);


Функция глКурсДляВалюты(Валюта,ДатаКурса) Экспорт
     
     Если ПустоеЗначение(ДатаКурса)=1 Тогда
           ДатаКурса=РабочаяДата();
     КонецЕсли;      
     
     Если ТипЗначенияСтр(ДатаКурса)="Документ" Тогда
           ДатаКурса=ДатаКурса.ДатаДок;
-- не вытаскивает курс на документ, т.к. у меня параметр типа дата
     КонецЕсли;      

     глЗапросПоВалютам.УстПараметр(1,ДатаКурса);
     
     Если Валюта=Рубли Тогда
           // Для базовой валюты курс всегда равен 1, поэтому отображаем курс Основной валюты
           глЗапросПоВалютам.УстПараметр(2,Константа.ОсновнаяВалюта);
     Иначе    // для других валют записываем их собственный курс
           глЗапросПоВалютам.УстПараметр(2,Валюта);
     КонецЕсли;
     
     Возврат глЗапросПоВалютам.ВыполнитьСкалярный();
     
КонецФункции
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #14 - 10. Декабря 2009 :: 08:27
Печать  
Если же поставить top 1

Select top 1 * from _1SCONST(NOLOCK)
where ID=92 and OBJID='     2   '
and DATE<='Oct  1 2009 12:00:00:000AM'
order by ID DESC, OBJID DESC, DATE DESC, TIME DESC, DOCID DESC


Select top 1 * from _1SCONST(NOLOCK)
where ID=92 and OBJID='     2   '
and DATE<='Oct  1 2009 12:00:00:000AM'
order by DATE DESC

Для обоих запросов sql выбрал index seek  IDD
при этом  стоимость стала 3 вместо 0 при scan cluster index
  
Наверх
 
IP записан
 
elkpro
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 145
Зарегистрирован: 19. Мая 2006
Re: Медленное получение значения периодического реквизита
Ответ #15 - 10. Декабря 2009 :: 08:35
Печать  
Ну если поставить TOP 1 понятно, что проблем бы не было. Только как ты это скажешь делать 1С?
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #16 - 10. Декабря 2009 :: 09:27
Печать  
elkpro писал(а) 10. Декабря 2009 :: 08:35:
Ну если поставить TOP 1 понятно, что проблем бы не было. Только как ты это скажешь делать 1С?

Не понял кто мешает
вместо

Процедура Сформировать1()
     Спр1 = СоздатьОбъект("Справочник.Валюты");
     Спр1.ИспользоватьДату(Дата1);
     Спр1.НайтиЭлемент(Вал1);
     Зн1 = Спр1.Текущ_курс;
     Сообщить("метод1 на дату = " + Дата1 + " курс = " + Зн1);
КонецПроцедуры

использовать внутри сформировать1 прямой запрос

Select top 1 * from _1SCONST(NOLOCK)
where ID=92 and OBJID='     2   '
and DATE<='Oct  1 2009 12:00:00:000AM'
order by DATE DESC

  
Наверх
 
IP записан
 
elkpro
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 145
Зарегистрирован: 19. Мая 2006
Re: Медленное получение значения периодического реквизита
Ответ #17 - 10. Декабря 2009 :: 09:55
Печать  
Так ты определись, что ты хочешь - всю конфигурацию перелопатить на предмет нахождения таких конструкций и замену их на прямой запрос или ничего не трогая ускорить их выполнение.
Практика показывает, что лучше переделать где это можно. Я тебе написал пример в посте #13.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #18 - 10. Декабря 2009 :: 10:02
Печать  
(elkpro) Давай не будем переходить на личности.
При 163  строках меня устроит любой метод. (валюта режется раз в год)

Ну а (all)  сможет из этой ветки выбрать что ему больше подходит.

  
Наверх
 
IP записан
 
elkpro
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 145
Зарегистрирован: 19. Мая 2006
Re: Медленное получение значения периодического реквизита
Ответ #19 - 10. Декабря 2009 :: 10:18
Печать  
Никто не переходит на личности. Извини если что не так сказал.
Я просто обращаю внимание на то, что для начала нужно определить что в итоге хочешь достичь и какими средствами.
Твоя проблема была в медленном получении периодических реквизитах, а конкретно при выборке данных из таблицы _1sconst.
Здесь есть два решения:
1. Менее трудозатратный, но не всегда гарантирует результат
2. Трудозатратный, но с гарантированным результатом.

  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #20 - 11. Декабря 2009 :: 06:38
Печать  
Сегодня проверил как работает $ПоследнееЗначение
Есть код
Код
Выбрать все
Процедура Сформировать4()
Запрос = СоздатьОбъект("ODBCRecordSet");
ТекстЗапроса = "
|SELECT  
|    $ПоследнееЗначение.Валюты.Текущ_курс(:ВыбID , :ВыбДата)
|";
Запрос.УстановитьТекстовыйПараметр("ВыбID", Вал1);
Запрос.УстановитьТекстовыйПараметр("ВыбДата", Дата1);
	Запрос.Отладка(1);
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
Сообщить("метод4 на дату = " + Дата1 + " курс = " + ТЗ.ПолучитьЗначение(1,1) );
КонецПроцедуры
 


код sql
SELECT  
   (
select top 1
cast(c92_vv.value as numeric(9, 4))
from
_1sconst as c92_vv (nolock)
where
c92_vv.id = 92 and
c92_vv.objid = '     2   ' and
(c92_vv.date <= '20091001')
order by c92_vv.date desc, c92_vv.time desc, c92_vv.docid desc, c92_vv.row_id desc
)
Т.е один в один что сказано в посте 6 или посте 13.

PS тоже в сортировке нет полей ID DESC, OBJID DESC
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #21 - 11. Декабря 2009 :: 06:43
Печать  
Остался один вопрос
Зачем в родном 1с запросе

exec sp_executesql N'Select * from _1SCONST(NOLOCK)
where ID=@P1 and OBJID=@P2 and DATE<=@P3
order by ID DESC, OBJID DESC, DATE DESC, TIME DESC, DOCID DESC'
, N'@P1 int,@P2 varchar(9),@P3 datetime', 92, '     2   ', 'Oct  1 2009 12:00:00:000AM'

сортировке используется ID DESC, OBJID DESC, в этом есть
какой-то смысл, это баг , может быть так надо было писать под sql 6.5 или что-то еще ?
Может этот вопрос вынести в отдельную тему ?
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #22 - 11. Декабря 2009 :: 07:23
Печать  
ORDER BY от 1С нагляднее для программиста и не приводит к выполнению лишней работы сервером. Т.е. это не баг.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
elkpro
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 145
Зарегистрирован: 19. Мая 2006
Re: Медленное получение значения периодического реквизита
Ответ #23 - 11. Декабря 2009 :: 08:56
Печать  
Z1 писал(а) 11. Декабря 2009 :: 06:38:
Сегодня проверил как работает $ПоследнееЗначение
Есть код
Код
Выбрать все
Процедура Сформировать4()
Запрос = СоздатьОбъект("ODBCRecordSet");
ТекстЗапроса = "
|SELECT  
|    $ПоследнееЗначение.Валюты.Текущ_курс(:ВыбID , :ВыбДата)
|";
Запрос.УстановитьТекстовыйПараметр("ВыбID", Вал1);
Запрос.УстановитьТекстовыйПараметр("ВыбДата", Дата1);
	Запрос.Отладка(1);
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
Сообщить("метод4 на дату = " + Дата1 + " курс = " + ТЗ.ПолучитьЗначение(1,1) );
КонецПроцедуры
 


код sql
SELECT  
   (
select top 1
cast(c92_vv.value as numeric(9, 4))
from
_1sconst as c92_vv (nolock)
where
c92_vv.id = 92 and
c92_vv.objid = '     2   ' and
(c92_vv.date <= '20091001')
order by c92_vv.date desc, c92_vv.time desc, c92_vv.docid desc, c92_vv.row_id desc
)
Т.е один в один что сказано в посте 6 или посте 13.

PS тоже в сортировке нет полей ID DESC, OBJID DESC


В данном случае сортировка по дате, только для того, чтобы вытащить последнее значение из всего кол-ва значений по дате и видимо ID и OBJID не влияют на индекс, т.к. он уже отфильтрован по ним.
В плане запросе такой запрос не формирует раздела SORT
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #24 - 11. Декабря 2009 :: 08:57
Печать  
Цитата:
ORDER BY от 1С нагляднее для программиста и не приводит к выполнению лишней работы сервером. Т.е. это не баг.

Ну да по сравнению с тем что возвращается весь набор
значений вместо одной строки это вообще не ошибка ( даже под микроскопом не увидишь ).

Далее рассмотрим ситуацию этот запрос сидит в кеше запросов все ок
Если по каким либо причинам этот запрос часто перекомпилируется
то на то чтобы из сортировки выбросить поля ID OBJID (что показал план выполнения) оптимизатору запросов надо немного потратить свое время. Вот об этом ничтожном времени и идет речь.
  
Наверх
 
IP записан
 
elkpro
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 145
Зарегистрирован: 19. Мая 2006
Re: Медленное получение значения периодического реквизита
Ответ #25 - 11. Декабря 2009 :: 09:01
Печать  
Если поставить
order by c92_vv.ID, c92_vv.OBJID, c92_vv.date desc, c92_vv.time desc, c92_vv.docid desc, c92_vv.row_id desc
как в оригинале, то план запроса уже использует Cluster Index Scan.
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #26 - 11. Декабря 2009 :: 09:10
Печать  
Z1 писал(а) 11. Декабря 2009 :: 08:57:
Если по каким либо причинам этот запрос часто перекомпилируется
то на то чтобы из сортировки выбросить поля ID OBJID (что показал план выполнения) оптимизатору запросов надо немного потратить свое время. Вот об этом ничтожном времени и идет речь.

Если бы, да кабы..  Злой Нет никакой ложки сортировки.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #27 - 11. Декабря 2009 :: 09:12
Печать  
elkpro писал(а) 11. Декабря 2009 :: 09:01:
Если поставить
order by c92_vv.ID, c92_vv.OBJID, c92_vv.date desc, c92_vv.time desc, c92_vv.docid desc, c92_vv.row_id desc
как в оригинале, то план запроса уже использует Cluster Index Scan.

В оригинале так:
order by c92_vv.ID desc, c92_vv.OBJID desc, c92_vv.date desc, c92_vv.time desc, c92_vv.docid desc, c92_vv.row_id desc
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #28 - 11. Декабря 2009 :: 09:49
Печать  
elkpro писал(а) 11. Декабря 2009 :: 09:01:
Если поставить
order by c92_vv.ID, c92_vv.OBJID, c92_vv.date desc, c92_vv.time desc, c92_vv.docid desc, c92_vv.row_id desc
как в оригинале, то план запроса уже использует Cluster Index Scan.

Да это не важно ( не об этом речь если sql выбрал другой индекс обхода с его точки зрения sql так запрос будет отработан быстрее )
а речь о том что если посмотришь план выполнения sort
то поля ID OBJID отброшены.
  

test1.JPG ( 69 KB | Загрузки )
test1.JPG
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #29 - 11. Декабря 2009 :: 10:20
Печать  
А теперь расскажи, как у тебя из select * получилось select cast(c92_vv.value... ?
Смех
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #30 - 11. Декабря 2009 :: 10:28
Печать  
berezdetsky писал(а) 11. Декабря 2009 :: 10:20:
А теперь расскажи, как у тебя из select * получилось select cast(c92_vv.value... ?
Смех

ну это  в qa ,было много запросов план был сделан по всем. Вот еще раз сделал
  

test2.JPG ( 115 KB | Загрузки )
test2.JPG
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #31 - 11. Декабря 2009 :: 12:32
Печать  
Как всё плохо..  Ужас

Если в таблице больше 1600 записей - обнови статистику with fullscan.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #32 - 12. Декабря 2009 :: 08:49
Печать  
berezdetsky писал(а) 11. Декабря 2009 :: 12:32:
Как всё плохо..  Ужас

Если в таблице больше 1600 записей - обнови статистику with fullscan.

Выполнил   статистику
UPDATE STATISTICS    _1sconst WITH FULLSCAN

после этого
таблице констант строк = 15242
Select count(*) from _1SCONST(NOLOCK)


значений по курсу доллара =  207
Select count(*) from _1SCONST(NOLOCK)
where ID=92
and OBJID='     2   '


Картинка таже самая .Что не так. В чем ужас ?
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #33 - 12. Декабря 2009 :: 17:39
Печать  
Z1 писал(а) 10. Декабря 2009 :: 06:58:
Еще больше ускорить можно если эти новые запросы оформить как хранимые процедуры.

На самом деле, клиент 1С кеширует результат select *, и, при последующих обращениях к реквизиту, больше не посылает запросов на сервер. В отличие от предлагаемых тобой select top 1 *.

Z1 писал(а) 11. Декабря 2009 :: 08:57:
Если по каким либо причинам этот запрос часто перекомпилируется

sp_executesql там - именно для того, чтобы "to reuse the execution plan it generates for the first execution".

Z1 писал(а) 12. Декабря 2009 :: 08:49:
Картинка таже самая .Что не так. В чем ужас ?

В том, что при избирательности в 1.36% сканируется вся таблица, вместо поиска по индексу. Для таблицы размером в два с лишним мегабайта это уже играет роль. Не возьмусь ставить диагноз по фотографии, но что-то с твоим сервером не в порядке.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #34 - 14. Декабря 2009 :: 06:04
Печать  
berezdetsky писал(а) 12. Декабря 2009 :: 17:39:
Z1 писал(а) 10. Декабря 2009 :: 06:58:
Еще больше ускорить можно если эти новые запросы оформить как хранимые процедуры.

На самом деле, клиент 1С кеширует результат select *, и, при последующих обращениях к реквизиту, больше не посылает запросов на сервер. В отличие от предлагаемых тобой select top 1 *

Об этом можно более подробней. Непонятно.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Медленное получение значения периодического реквизита
Ответ #35 - 14. Декабря 2009 :: 06:14
Печать  
berezdetsky писал(а) 12. Декабря 2009 :: 17:39:
Z1 писал(а) 12. Декабря 2009 :: 08:49:
Картинка таже самая .Что не так. В чем ужас ?

В том, что при избирательности в 1.36% сканируется вся таблица, вместо поиска по индексу. Для таблицы размером в два с лишним мегабайта это уже играет роль. Не возьмусь ставить диагноз по фотографии, но что-то с твоим сервером не в порядке.

Еще раз переиндексировал и обновил статистику.
Может влияет на ситуацию еще и распределение дат
Всего разных дат Select DISTINCT DATE from _1SCONST = 1363


Если ограничить значение снизу
Select * from _1SCONST(NOLOCK)
where ID=92
and OBJID='     2   '
and DATE <= 'Oct  1 2009 12:00:00:000AM'
and DATE >= 'Jan  2007  12:00:00:000AM'
order by DATE DESC, TIME DESC, DOCID DESC
то запрос идет по IDD
При более ранних датах(снизу)  sql сервер выбирает кластерный индекс.

  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать