Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Использование индексов (ДБФ) (число прочтений - 10580 )
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Использование индексов (ДБФ)
11. Апреля 2007 :: 10:32
Печать  
Подскажите пожалуйста, как можно в запросе заставить драйвер FoxPro
использовать индексы?
В документации по Fox написано что он понимает индексные файлы CDX,
но в реальности запрос что с отбором по индексному полю, что нет - выполняется по времени практически
одинаково (отбор по одному элементу дает 10-20% выигрыша, по нескольким 10-20 проигрыша )
Проверял на нескольких совершенно разных запросах.

На форуме на эту тему ничего не нашел.
Используется доступ через oledb.
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование индексов (ДБФ)
Ответ #1 - 11. Апреля 2007 :: 11:11
Печать  
Опиши подробнее ситуации на конкретных примерах.
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Использование индексов (ДБФ)
Ответ #2 - 11. Апреля 2007 :: 12:18
Печать  
Например простой тестовый запрос  
Код
Выбрать все
    |SELECT  
    |	TablProdaz.Товар as [Товар $Справочник.Номенклатура]
    |	,SUM(TablProdaz.Количество) as Количество
    |	,SUM(TablProdaz.Себестоимость) as Себестоимость
    |	,SUM(TablProdaz.ПродСтоимость) as ПродСтоимость  
    |
    |FROM
    | (
    |    SELECT  
    |		$РегПродажи.Товар as Товар,
    |		$РегПродажи.Клиент as Клиент,
    |		$РегПродажи.Фирма as Фирма,
    |		$РегПродажи.Склад as Склад,
    |		$РегПродажи.Количество as Количество,
    |		$РегПродажи.Себестоимость as Себестоимость,
    |		$РегПродажи.ПродСтоимость as ПродСтоимость,
    |		РегПродажи.IDDoc as Док
    |	FROM
    |			$Регистр.Продажи as РегПродажи
    |	WHERE  (РегПродажи.Date BETWEEN :НачДата~~ AND :КонДата~~)
    |       AND($РегПродажи.Товар=:ВыбНоменкл)  // этого условия нет, когда по всем товарам
    |) as TablProdaz  
    |GROUP BY   Товар
 


На измерение Товар регистра Продажи повесим "отбор движений"
Результаты замеров :
_________________________________

С индексом

По выб товару   : 0.115с
По всем товарам : 0.426с
_________________________________

Без индекса

По выб   товару : 0.125с
По всем товарам : 0.435с
_________________________________

Описание поля таблицы движений при установке индекса


#-----Fields-------
F=SP5227    |(P)Товар
#----Indexes------
I=VIA5227  |VIA5227       |0     |SP5227,DATE,TIME,IDDOC,LINENO,ACTNO    

________________________________  

Как видно от установки индекса время выполнения практически не влияет.
Это тестовый пример. В реальной базе также никаких отличий не нашел.
Особенно это плохо из за с таблицы Констант
(Индекс : ID,OBJID...   )  и 1SJOURN.

В Fox е можно в процедурах указывать индекс. Может и здесь как то можно?
  
Наверх
 
IP записан
 
varelchik
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 788
Зарегистрирован: 22. Мая 2006
Re: Использование индексов (ДБФ)
Ответ #3 - 11. Апреля 2007 :: 13:43
Печать  
Дык так оно и есть.
Я давеча поднимал этот вопрос.
по пока так никто решения и не дал.
только у меня по другому было.
соединяю таблицу итогов и журнал.
И никакой практически разницы что с ограничением периода что без резальтаты недалеко друг от друга уходять.
Хотя когда на работающей базе т.е. с юзьверами проверял то иногда выбрасывало сообщение что типа ошибка доступа к файлу 1sjoun.cdx выходит типа использует или по крайней мере обращается,но толку не дает.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Использование индексов (ДБФ)
Ответ #4 - 23. Апреля 2007 :: 07:30
Печать  
В качестве up.
Чтобы драйвер лучше понимал запрос условие  изменено на
Код
Выбрать все
|WHERE        ($РегПродажи.Товар=:ВыбНоменкл)  
|          AND  (РегПродажи.Date BETWEEN :НачДата~~ AND :КонДата~~)
 


Т.е. в ряде условий поле с индексом вынесено на первое место.
Наблюдается ускорение. Опять никак не связанное с наличием или отсутствием индекса.

Также испытание проведено по ряду запросов в живой базе, 30 человек.
Отмечена закономерность - чем селективнее запрос - тем быстрее работает 1С запрос,
запрос 1С++ убыстряется крайне незначительно.
На одном товаре уже наблюдается проигрыш прямого запроса.

Вообщем если не решить проблему с индексами, получается что прямые запросы на ДБФ базах
представляют интерес только для выборок без отборов, а это менее 10% всех запросов к базе.

Может все таки есть какое нибудь решение?

  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Использование индексов (ДБФ)
Ответ #5 - 23. Апреля 2007 :: 09:30
Печать  
Цифры к предыдущему посту.
Комбинированный отчет с остатками, резервами, заказами...

1С чистый (в транзакции) (в сек) в живой базе (ДБФ).

все товары---------------- 8.532
группа товаров---------- 7.01
два товара---------------- 6.239
один товар---------------- 0.35

.................................................................
прямой запрос

все товары---------------- 3.133
группа товаров---------- 3.431
два товара---------------- 3.161
один товар---------------- 3.006
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Использование индексов (ДБФ)
Ответ #6 - 23. Апреля 2007 :: 14:18
Печать  
Возможно проблема связана с режимом сортирировки
"каждый индекс в отдельности запоминает тот режим сортировки при котором он был создан "
http://www.foxclub.ru/articles/index.php?id=35
Изменение в строке подключения
Код
Выбрать все
|Collating Sequence=RUSSIAN; 


на
Код
Выбрать все
|Collating Sequence=MACHINE;  



дало по предыдущему запросу

прямой запрос (Collating Sequence=MACHINE)

все товары---------------- 1.15
группа товаров---------- 1.00
два товара---------------- 0.77
один товар---------------- 0.75

Если кто использует ДБФ - проверьте пожалуйста (чтобы база не лежала только локально и было подключено несколько человек)
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование индексов (ДБФ)
Ответ #7 - 23. Апреля 2007 :: 15:48
Печать  
Выложил бы нормальный пример, чтобы можно было быстро проверить Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Использование индексов (ДБФ)
Ответ #8 - 24. Апреля 2007 :: 08:43
Печать  
Выкладываю тест.
Подходит для любых конфигураций на торговле, где есть регистр
с измерением типа Документ и измерением "Номенклатура","Количество".
Запрос динамический, т.е. создание таблиц не используется.
По умолчанию данные под типовую торговлю

В запросе используется соединение регистра с журналом по IDDOC - как с наиболее тяжелой таблицей,
и у которой есть индекс по IDDOC.

На маленьких базах(демо) использовать не очень корректно , так как затраты на компиляцию занимают
основное время.
  

Test.ert ( 34 KB | Загрузки )
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Использование индексов (ДБФ)
Ответ #9 - 24. Апреля 2007 :: 20:06
Печать  
kiruha писал(а) 24. Апреля 2007 :: 08:43:
Выкладываю тест.

Вот такой запрос:
Код
Выбрать все
    TablRezervov= "
	|SELECT
	|	 right($РегРезервы."+СокрЛП(ИзмерениеРегистра)+",9) as [Док $Документ],
	|	    ЖурРезервов.IDDOCDEF as  Док_Вид,
	|	 $РегРезервы.Номенклатура as [Номенклатура $Справочник.Номенклатура],
	|		$РегРезервы.Количество as Количество
	|	FROM
	|			$РегистрИтоги."+СокрЛП(НазваниеРегистра)+" as РегРезервы
	|	LEFT JOIN 1sjourn as ЖурРезервов ON ЖурРезервов.IDDoc = right($РегРезервы."+СокрЛП(ИзмерениеРегистра)+",9)
	|	WHERE
	|			РегРезервы.PERIOD = :ДатаПериодаОстатков~~
	|			AND $РегРезервы.Количество <> 0
	|  "+УсловиеНаОбъект("$РегРезервы.Номенклатура",ВыбТовары)+"
	|";
 


У меня выполняется в 8 раз быстрее.
Исходный вариант выполняется за 0.8 с.
Этот вариант с "collating = machine" за 0.1 с.
Этот вариант с "collating = russian" за 0.4 с.
Этот вариант с "collating = machine" + фильтр по одному товару за 0.055с
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование индексов (ДБФ)
Ответ #10 - 25. Апреля 2007 :: 04:57
Печать  
Так, срочно переходим на такой вариант Улыбка
Ужас, а ты проверял этот вариант на выборке с top 1 ?
будет ли ускорение по сравнению с прошлым разом?
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
varelchik
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 788
Зарегистрирован: 22. Мая 2006
Re: Использование индексов (ДБФ)
Ответ #11 - 25. Апреля 2007 :: 06:12
Печать  
Уважаемые товарищи!
И все таки я возвращаюсь к наложению условий на Дату в присоединенном журнале.
ТекстЗапроса="
|Select $Рег.Товар ,sum($Рег.РасходКво)
|from $Регистр.Обороты_М as Рег
|left join 1sjourn as Журнал on Журнал.iddoc=right(Рег.iddoc,9)
|where Журнал.date between :НачДата~~ and :КонДата~~
|Group by $Рег.Товар
|";
Разницы практичекси никакой. что месяц что день.
причем бем больше таблицы тем больше тормоза!

  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Использование индексов (ДБФ)
Ответ #12 - 25. Апреля 2007 :: 08:27
Печать  
varelchik писал(а) 25. Апреля 2007 :: 06:12:
Уважаемые товарищи!
И все таки я возвращаюсь к наложению условий на Дату в присоединенном журнале.
ТекстЗапроса="
|Select $Рег.Товар ,sum($Рег.РасходКво)
|from $Регистр.Обороты_М as Рег
|left join 1sjourn as Журнал on Журнал.iddoc=right(Рег.iddoc,9)
|where Журнал.date between :НачДата~~ and :КонДата~~
|Group by $Рег.Товар
|";
Разницы практичекси никакой. что месяц что день.
причем бем больше таблицы тем больше тормоза!



В этом нет ничего удивительного. Судя по запросу сначала драйверу надо соединить
таблицы по iddoc (возможно используя индекс) и лишь потом убрать лишнее.

Если селективность по дате выше чем по iddoc можно использовать
Код
Выбрать все
        |Select $Рег.Товар ,
	|sum($Рег.Количество) as Кол
	|from 1sjourn as Журнал  
	|left join   $Регистр.Продажи as Рег
	|         on Журнал.iddoc=right(Рег.iddoc,9)  
	|where  Журнал.date between :НачДата~~ and :КонДата~~
	|       AND (Журнал.$ФлагРегистра.Продажи = 1)
	|Group by $Рег.Товар  



Как видно одновременно и то и другое сделать не получается без установки флага быстрой обработки движений.
Что сам делаю и советую. Тем более оборотный регистр.
........
Uzhast писал(а) 24. Апреля 2007 :: 20:06:
Вот такой запрос:
........
У меня выполняется в 8 раз быстрее.

Да, большое спасибо , учту при написаниии запросов Улыбка

.....
Кстати, в описании индексов 1SJOURN в файле 1Cv7.DD встречается DOCNO(UPPER)
Между тем для Fox в режиме национальной сортировки регистр букв игнорируется.

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


Дорогу осиливает идущий

Сообщений: 137
Зарегистрирован: 07. Июля 2006
Re: Использование индексов (ДБФ)
Ответ #13 - 25. Апреля 2007 :: 10:10
Печать  
(9) Подтверждаю значительное ускорение при использовании
collating = machine.
Использовал журнал проводок в соединении с журналом документов.
8-кратного ускорения не наблюдал, но 2-4 кратное прослеживается четко, особенно на больших выборках.
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Использование индексов (ДБФ)
Ответ #14 - 11. Мая 2007 :: 03:23
Печать  
artbear писал(а) 25. Апреля 2007 :: 04:57:
Ужас, а ты проверял этот вариант на выборке с top 1 ?
будет ли ускорение по сравнению с прошлым разом?

А смысл? И так ведь понятно, что драйвер такие запросы обрабатывает неоптимально. Или ты про сервис-пак? Надо будет еще сервис-пак погонять...

Вообще, ИМХО, в исходном запросе проявляется недостаточность мозгов у драйвера. Он вообще умный, но не всегда Улыбка В запросе делается сначала выборка по 1sjourn, а потом она джойнится с резервами. Вероятно, драйвер делает полную выборку по 1sjourn, а потом отсеивает ненужное при помощи джойна. 1sjourn содержит заголовки всех документов за все время жизни базы. В результате, выборка по этой таблице занимает бОльшую часть времени выполнения запроса. Поэтому фильтры по товару почти не оказывают влияния на время запроса.

Как говорится, "на оптимизатор надейся, но и сам не плошай" Улыбка Лучше запрос начинать с таблицы, которая даст наименьшее количество записей, а потом к ней уже джойниться. В данном случае это резервы.
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать