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



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Тема Использование индексов (ДБФ) часть 2.
13. Июля 2007 :: 09:08
Печать  
Эта тема является продолжением http://www.1cpp.ru/forum/YaBB.pl?num=1176287559
(использование индексов)
Если кратко – то было установлено, что драйвер FoxPro не использует индексы 1С,
из за чего не наблюдается существенного ускорения при наложении фильтров.

Было экспериментально установлено, что использование
Collating Sequence=MACHINE ускоряет работу в среднем в 3-4 раза.
Рекомендация вошла в FAQ по прямым запросам.
Данная настройка у меня используется уже 3 месяца в живой базе –
ускорение подтверждаю, глюков не замечено.

Тем не менее.
Метод оптимизации по индексу обещает ускорение до 10 000 раз – с ускорением в 3 раза это как то не вяжется.
Также можно установить индекс по товару в регистре (например «Продажи», галочку у «Отбор движений») и сравнить время выполнения запроса с условием

Код
Выбрать все
WHERE $РегПродажи.Товар = :ВыбТовар 



Есть ли индекс, нет ли индекса – время выполнения не меняется.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #1 - 13. Июля 2007 :: 09:10
Печать  
Структура индексов в 1С.
Чтобы посмотреть структуру индексов в 1С понадобится установить FoxPro 9.
Ассоциируем программу с файлами ДБФ при установке.
Щелкаем по файлу (таблице) ДБФ, например 1SJOURN.
FoxPro спросит Code Page (кодовую страницу).
Выбираем «1251 Russian Windows».
Будет открыта таблица.
Далее идем в меню, путь «View / Table Designer».
Откроется окно «структуры таблицы», выбираем закладку Indexes и изучаем (см. Картинку)

Что мы видим?
Order (сортировка) – возрастание.
Collate – Machine (т.е. действительно Machine, а не Russian или что то другое).
Самое интересное Expression – собственно выражения по которым строится индекс.
В 1С они практически всегда - строковые сложные выражения.
Исключение IDDOC – строковое простое.

Например расммотрим индекс ACDATETIM (по дате в журнале)
Программист 1С ожидает , что это
    - просто «дата».
В файле 1CV7.DD написано
   -«ACDATETIM | Date+Time+ID  |0     |DATE,TIME,IDDOC»
Фактически же это
  - «DTOS(date)+time+iddoc»
  

2.jpg ( 77 KB | Загрузки )
2.jpg
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #2 - 13. Июля 2007 :: 09:13
Печать  
Оптимизация(использование индеков) в FoxPro (продолжение)

В FoxPro как и в 1С допускается хранение индексов в файлах CDX.
CDX файл это не индекс , а «контейнер» хранящий несколько индексов по соответствующей таблице.

Русскоязычная статья  по оптимизации – http://www.foxclub.ru/articles/index.php?id=45
(допонительно кому нужно «Русский Help для Visual FoxPro» включая функции
http://www.foxclub.ru/rhproject/project/ )
Основная статья по оптимизации (к сожалению на англ.)
"Using Rushmore Query Optimization to Speed Data Access"
http://msdn2.microsoft.com/en-us/library/1f5d2sa3(VS.80).aspx

Наиболее важные моменты для оптимизации языка запросов.
Оптимизации поддаются предложения WHERE, JOIN, ORDER BY.

Создание базового Optimizable выражений
Основные оптимизируемые выражения могут быть одной из двух следующих форм :
eIndex relOp eExp
- или
eExpr relOp eIndex
Где
•      eIndex  - полностью соответствуют выражению в индексе.
•      eExpr   - является любое выражение и может включать переменные и поля от других, не связанных таблиц.
•      relOp только следующие реляционные операторы: <, >, =, <=, >=, <>, #, ==, or != Вы также можете использовать ISNULL( ) , BETWEEN( ) , or INLIST( ) функции (или их эквиваленты SQL, как IS NULL и т.д.).

Очень важно понять, когда запросы будут оптимизированы и, когда они не будут. Visual FoxPro оптимизирует поиск условий, найдя точное соответствие между левой части выражение фильтра и индекса.
Если условие является сложным(много условий на таблицу), то такое сложное условие также может быть оптимизировано.

Результат (оптимизация) при соединении выражений.

Basic Expression 1      Operator      Basic Expression 2      Query Result
Optimizable      AND      Optimizable      Fully Optimizable
Optimizable      OR      Optimizable      Fully Optimizable
Optimizable      AND      Not Optimizable      Partially Optimizable
Optimizable      OR      Not Optimizable      Not Optimizable
Not Optimizable      AND      Not Optimizable      Not Optimizable
Not Optimizable      OR      Not Optimizable      Not Optimizable
—      NOT      Optimizable      Fully Optimizable
—      NOT      Not Optimizable      Not Optimizable

Рекомендации – первое условие должно быть полностью оптимизируемым, второе – желательно.
При соединении нескольких таблиц – первой должна быть наиболее оптимизируемая таблица с соответствующими оптимизирующими выражениями.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #3 - 13. Июля 2007 :: 09:14
Печать  
Применение в 1С. (продолжение)

Вы должны посмотреть структуру индекса, который хотите использовать, в FoxPro.

Если FoxPro нету, то смотрим в 1СV7.DD "Indexed fields"
через запятую указаны поля. Нужно просто запятые заменить на "+" , если поле имеет тип DATE то
это поле преобразуется в строку при помощи DTOS(), если в скобках Upper то поле преобразуется функцией
Upper(), если число(Numeric) то функ. STR(ВыбПоле,Width) где Width размер числового поля,
в остальных случаях(ссылки ) без функций.


Например мы хотим выбрать документы из 1SJOURN за период .
Подходящий индекс – ACDATETIM (дата/время) : «DTOS(date)+time+iddoc»
Если использовать
Код
Выбрать все
|WHERE	Жур.Date BETWEEN :НачДата~~ AND :КонДата~~ 


то оптимизатор не найдет индекса, так как «Жур.Date»  не соответствует «DTOS(date)+time+iddoc»
     К счастью FoxPro поддерживает упорядочение строк – и можно использовать оператор          BETWEEN .
Длина строки «time+iddoc» равна 15.
Определим переменные МинСтрока= "               "
                                        МаксСтрока= "ZZZZZZZZZZZZZZZ"
Собственно условие
Код
Выбрать все
WHERE   DTOS(date)+time+iddoc BETWEEN (DTOS(:НачДата~~)+'		   ') AND (DTOS(:КонДата~~)+'ZZZZZZZZZZZZZZZ') 


(для простоты переменные МинСтрока и МаксСтрока не используются)
* kiruha отредактировано 13 июля 15:09
« Последняя редакция: 13. Июля 2007 :: 11:16 - kiruha »  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #4 - 13. Июля 2007 :: 09:18
Печать  
Тест
Исходный запрос.
|
Код
Выбрать все
SELECT
	|   Жур.$ОбщийРеквизит.Фирма as Фирма ,
	|   Жур.iddoc,
	|   Жур.IDDocDef
	|FROM
	|   1sjourn as Жур
	|
	|WHERE
	|   Жур.Date BETWEEN :НачДата~~ AND :КонДата~~
	| "; 



Модифицированный

Код
Выбрать все
 |SELECT
	|Жур.$ОбщийРеквизит.Фирма as Фирма ,
	|Жур.iddoc,
	|Жур.IDDocDef,
	| DTOS(date)+time+iddoc  as Индекс
	|FROM
	|1sjourn as Жур
	|
	|		WHERE
	| DTOS(date)+time+iddoc BETWEEN (DTOS(:НачДата~~)+'		   ') AND (DTOS(:КонДата~~)+'ZZZZZZZZZZZZZZZ')
	|
	|ORDER BY  Индекс
    | "; 


Испытание в живой базе, выборка за 1 день.
Первый – 2.5 сек
Второй -  0.015
Разница – в 150 раз.

P.S.
Данное исследование потребовало от меня много сил и времени (читай денег) , если не трудно – при использовании упоминайте автора Улыбка
в предыдущем случае (с Collating Sequence=MACHINE) этого не было Улыбка

Также остались нерассмотренными сложные запросы с соединением
таблиц и с переменными динамическими условиями (требуется ручная настройка условий для использования индексов – оптимизация запроса) – если кто присоединится к изучению этого вопроса – будет здорово Улыбка

Хотел прикрепить статью - но прав нету.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #5 - 13. Июля 2007 :: 10:41
Печать  
Еще пример.
Запрос к регистру остатков на ТА.

У регистров остатков всегда есть индекс вида
DTOS(period)+измерение1+измерение2+....

Типичная задача - остатки товара при заданной фирме и складу
Код
Выбрать все
| SELECT
	|		$РегОстатков.Товар as Товар,
	|		$РегОстатков.ОстатокТовара as ОстатокНаСкладе
	|		FROM
	|			$РегистрИтоги.ОстаткиТоваров as РегОстатков
	|		WHERE
	|			РегОстатков.PERIOD = :ДатаПериодаОстатков~~
	|	     AND ($РегОстатков.Фирма=:выбФирма)
	|	     AND ($РегОстатков.Товар=:ВыбНоменкл)
	|	     AND ($РегОстатков.Склад=:выбСклад)
 



Оптимизированный по индексу
Код
Выбрать все
	| SELECT
	|		$РегОстатков.Товар as Товар,
	|		$РегОстатков.ОстатокТовара as ОстатокНаСкладе
	|		FROM
	|			$РегистрИтоги.ОстаткиТоваров as РегОстатков
	|		WHERE
	|			д = DTOS(:ДатаПериодаОстатков~~)+:выбФирма+:ВыбНоменкл+:выбСклад
 



Первый - 0.45 сек
Второй - 0.005 сек
  
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #6 - 13. Июля 2007 :: 11:07
Печать  
В 150 и 90 раз?  Ужас
1С перед каждым замером закрывалась/открывалась?
  
Наверх
ICQ  
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #7 - 13. Июля 2007 :: 11:24
Печать  
spock писал(а) 13. Июля 2007 :: 11:07:
В 150 и 90 раз?  Ужас
1С перед каждым замером закрывалась/открывалась?


Измерения проводились на живой базе, которая хранится на сервере.
Работает сейчас 24 чел.
На тестовой базе на локальном диске отличия существенно меньше - видимо
из за того, что не нужно качать файлы.
1С не закрывалась. Даже OLE подключение не прерывалось.

Выше я написал - как узнать индекс не имея FoxPro.

Все результаты желательно проверить у других участников.
  
Наверх
 
IP записан
 
varelchik
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 788
Зарегистрирован: 22. Мая 2006
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #8 - 13. Июля 2007 :: 11:25
Печать  
Ну на счет 150 и 90 я бы не сказал а вот на счет 50 это точно!
Вот только на счет сетки не пробовал, но в принципе можно будет и по сети спробовать.
  
Наверх
 
IP записан
 
varelchik
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 788
Зарегистрирован: 22. Мая 2006
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #9 - 13. Июля 2007 :: 11:45
Печать  
Так же подтверждаю что по сети действительно выигрыш есть около 50-60 раз при чем очень сильно зависит от периода! меньше период больше выигрыш!
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #10 - 13. Июля 2007 :: 11:54
Печать  
Тут как-то не всё так однозначно.
Я помню твою прошлую проблему с кодировкой. Так вот у меня вообще не имеет значения стоит в строке подключения Рашн или Машин.
Потестировал у себя запрос, приведённый тобой выше по выборке из журнала документов (убрал из второго запроса сортировку и выборку поля "Индекс"). Вот результаты:

Цитата:
Период - 1 день:
Время выполнения по старой методике  = 0.111
Время выполнения по новой методике  = 0.002

Период - 1 месяц:
Время выполнения по старой методике  = 0.142
Время выполнения по новой методике  = 0.039

Период - 1 квартал:
Время выполнения по старой методике  = 0.188
Время выполнения по новой методике  = 0.117

Период - полгода:
Время выполнения по старой методике  = 0.229
Время выполнения по новой методике  = 0.187

Период - год:
Время выполнения по старой методике  = 0.53
Время выполнения по новой методике  = 0.654

Итого:
1) на периоде в 1 день увеличение скорости в ~50 раз
2) на периоде в 1 год уменьшение скорости в ~1,2 раза
3) у меня время выполнения запроса не меняется при смене "Collating Sequence" с "RUSSIAN" на "Machine"
  
Наверх
 
IP записан
 
varelchik
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 788
Зарегистрирован: 22. Мая 2006
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #11 - 13. Июля 2007 :: 12:28
Печать  
JohnyDeath писал(а) 13. Июля 2007 :: 11:54:
Тут как-то не всё так Итого:
1) на периоде в 1 день увеличение скорости в ~50 раз
2) на периоде в 1 год уменьшение скорости в ~1,2 раза
3) у меня время выполнения запроса не меняется при смене "Collating Sequence" с "RUSSIAN" на "Machine"

Ты ведь сам и ответил.
Ведь чем меньше период тем больше выигрыш.
Естетсвенно выходит что попадаем таки в индекс.
А на больших периодах это тута уже нандо на нескольких попытках пробовать.
Так что предложенная методика действительно позволяет правильно использовать индекс в запросе.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #12 - 13. Июля 2007 :: 12:35
Печать  
JohnyDeath писал(а) 13. Июля 2007 :: 11:54:
Тут как-то не всё так однозначно.
Я помню твою прошлую проблему с кодировкой. Так вот у меня вообще не имеет значения стоит в строке подключения Рашн или Машин.
Потестировал у себя запрос, приведённый тобой выше по выборке из журнала документов (убрал из второго запроса сортировку и выборку поля "Индекс"). Вот результаты:


Итого:
1) на периоде в 1 день увеличение скорости в ~50 раз
2) на периоде в 1 год уменьшение скорости в ~1,2 раза
3) у меня время выполнения запроса не меняется при смене "Collating Sequence" с "RUSSIAN" на "Machine"


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

У меня цифры на периоде в год
1. Старый - 3.0 сек
2.Новый - 2.5 сек.      Но это наверно потому, что у вас селективность по году меньше.

Вообщем не дай бог их везде подряд применять Улыбка

Насчет сортировки - нужно проверить через FoxPro.
Еще возможно дело в том - что есть  пара индексов в самых тяжелых таблицах - IDDOC в 1SJOURN например,
а также все ID в справочниках - которые не являются сложными строковыми выражениями.
Соответственно чтобы шла оптимизаци при JOIN по этим полям достаточно просто
проставить правильный "Collating Sequence" . Видимо отсюда и появилось ускорение в 3 раза.
Те запросы, которые не используют такие поля - соответственно не ускоряются.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #13 - 13. Июля 2007 :: 13:16
Печать  
13 сообщение в пятницу 13-го Улыбка

Кто нибудь знает - как порушить выбранный файл CDX?
Блокнотом не удалось.
Также рубил второго пользователя во время "обычного" запроса.
Ничего не изменилось, хотя программа попросила при входе переиндексироваться.

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


I Love YaBB 2!

Сообщений: 788
Зарегистрирован: 22. Мая 2006
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #14 - 13. Июля 2007 :: 14:03
Печать  
Касательно остатков понятно.
а вот как быть с оборотами?
Там же даты нету.
Есть только IDDOC
по нем соединяться?
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #15 - 13. Июля 2007 :: 15:00
Печать  
varelchik писал(а) 13. Июля 2007 :: 14:03:
Касательно остатков понятно.
а вот как быть с оборотами?
Там же даты нету.
Есть только IDDOC
по нем соединяться?


Если имеется ввиду обороты по регистру остатков.

По умолчанию 1С заводит только один индекс
IDLINE       |IDDOC,LINENO,ACTNO
т.е. iddoc+STR(lineno,4)+STR(actno,6)

Т.е. если интересует отбор по периоду, то только соединяться.

Оптимизация хранения индексов оставлена на усмотрение программиста.

Например, если поставить галочку "быстрая обработка движений" (я обычно ставлю для регистра продаж)
То появится поля DATE и TIME и индекс :

DATETIME     |DATE,TIME,IDDOC,LINENO,ACTNO
т.е. DTOS(date)+time+iddoc+STR(lineno,4)+STR(actno,6)

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

Также можно добавлять отборы движений по измерениям - появится сложный индекс по измерению.
  
Наверх
 
IP записан
 
Vaicartana
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 50
Местоположение: Far, Far Away...
Зарегистрирован: 29. Мая 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #16 - 15. Июля 2007 :: 00:53
Печать  
круто!
Если так все на самом деле, прошу у Кирилла разрешения включить все вышеизложенное в статью по работе с ДБФ.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #17 - 20. Августа 2007 :: 14:33
Печать  
Каждый индекс привязан к конкретной таблице, поэтому при соединении нескольких таблиц, чтобы индексы работали - нужно каждую соединяемую таблицу (в которой хотим и можем использовать индекс)  оформлять ввиде подзапроса .

Подзапрос составляется так, как было указано в предыдущих постах.

Пример : соединение с журналом в котором произведен отбор по индексу DOCTYPE (вид документа)
Код
Выбрать все
|  LEFT JOIN
|  ( SELECT  Жур.$ОбщийРеквизит.Автор as Автор,
|			  Жур.IDDoc as IDDoc
|	    FROM   1sjourn as  Жур   WHERE
|	   (Жур.iddocdef+DTOS(Жур.date)+Жур.time+Жур.iddoc  BETWEEN ($ВидДокумента.РасходнаяНакладная+DTOS(:НачДата~~)+'		   ') AND ($ВидДокумента.РасходнаяНакладная+DTOS(:КонДата~~)+'ZZZZZZZZZZZZZZZ')    )
|   )   as Журн  ON 



Здесь нужно  отметить, что делать такой подзапрос нужно крайне осторожно - у журнала  есть индекс IDDOC  и стандартное соединение происходит как правило по этому индексу. Оформляя подзапрос, мы делаем невозможным использование индекса IDDOC , т.е. в некоторых случаях результат будет хуже первоначального.
  
Наверх
 
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #18 - 28. Августа 2007 :: 12:38
Печать  
Подтвердить ускорение к Регистру итогов у меня не получилось, в случае когда одно из измерений неизвестно.

Старый метод - 1.976 сек.
Новый метод - 3.615 сек.

Соответственно база закрывалась после каждого запроса

Обработка во вложении


P.S. Может я что-то где-то не допонял  Смущённый
  

___DBF.ert ( 28 KB | Загрузки )

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #19 - 28. Августа 2007 :: 13:12
Печать  
а.В шаблоне у тебя все измерения одинаковые ,но наверно это просто описка .
...
б.Какова последовательность измерений?
В старой торговле, я сейчас посмотрел : Фирма,Товар,Склад а не Фирма,Склад,Товар
Т.е. должно быть
Код
Выбрать все
стрОстатков.Склад
 


последовательность важна т.к. это строковое сложение.

в. А особенно будет заметно если добавить еще условия по фирме и товару :
Код
Выбрать все
WHERE д
BETWEEN (DTOS(:ДатаПериодаОстатков~~)+:ВыбФирма+:ВыбТовар+'	   ')
 AND (DTOS(:ДатаПериодаОстатков~~)+:ВыбФирма+:ВыбТовар+'ZZZZZZZZZ') 

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



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #20 - 28. Августа 2007 :: 13:23
Печать  
Вообще наверно смысла нет вручную писать индексные выражения -дело довольно трудоемкое и громоздкое -
у меня в сыром виде есть специальный класс поддерживающий виртуальные функции -
там подстановка индексов происходит автоматически. Будет готов где то через неделю.
  
Наверх
 
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #21 - 28. Августа 2007 :: 13:34
Печать  
1. Действительно описка была в шаблоне

2. И опять же действительно напутал с порядком измерений

После правильной расстановки

0.933 сек. НОВЫЙ
1.898 сек. Старый

Так что всё таки - Кирил ты прав с индексами на все 100%
  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #22 - 29. Августа 2007 :: 07:39
Печать  
МАЛЕНЬКИЙ ВЕСЕЛЫЙ МОМЕНТ:

При использовании фильтра по индексному выражению вместо BETWEEN лучше использовать конструкцию "строкаВыражениеИндекса LIKE (строкаВыражениеФильтра)"

Причем строкаВыражениеФильтра не должна содержать "%" (любая последовательность символов) = тогда запрос будет тормозить очень сильно, а должна содержать "_" (один любой символ)

и самое главное Цитата:
LIKE "cExpression_" для условия Фильтра - полностью Оптимизируема


Пример для партий товаров в старой торговле во вложении

  

___DBF_001.ert ( 28 KB | Загрузки )

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
kiruha
1c++ power user
Отсутствует



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

Правда значимого ускорения я не выявил (видимо алгоритм один) - но заполнять условия так значительно удобнее.
(кроме случая когда идет выборка между двумя датами - тогда без BETWEEN не обойтись)

Например, если задан только склад - достаточно написать :
Код
Выбрать все
|WHERE д
|LIKE (DTOS(:ДатаПериодаОстатков~~)+'_________'+'_________'+:ВыбСклад)
 



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


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #24 - 29. Августа 2007 :: 10:27
Печать  
И еще одно наблюдение про предложение WHERE:

А ЕСЛИ МЫ ИСПОЛЬЗУЕМ СписокОбъектов -
1. придется писать громоздкое условие LIKE ... OR LIKE... для попадания в индекс
2. Использовать старинный метод IN SELECT (val FROM <ИмяВременнойТаблицы>)  - в таком случае мы опять не попадаем в индекс

либо

3. Вот такое хитрое соединение с временной таблицей
Код
Выбрать все
SELECT
             ВременнаяТаблица.val as Товар,
             ....
FROM
             $РегистрИтоги.ПартииТоваров as ПартииТоваров
INNER JOIN
	<ИмяВременнойТаблицыТоваров> as ВременнаяТаблица ON  
                          (ВременнаяТаблица.val = $ПартииТоваров.Товар) 



(у меня данных метод показал выйгрыш по скорости 15% про сравнению с "IN SELECT val")
  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #25 - 29. Августа 2007 :: 11:45
Печать  
lustin писал(а) 29. Августа 2007 :: 10:27:
1. придется писать громоздкое условие LIKE ... OR LIKE... для попадания в индекс


Однозначно.
- Существенно быстрее , если задана Фирма. Если Фирма (или любое другое измерение до измерения "Товар")
не задано, то условие "LIKE ... OR LIKE.. по товару " ничего не дает,
проще добавить стандартное условие на товар.
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #26 - 31. Августа 2007 :: 13:35
Печать  
Для счастливых обладателей TotalCommander'a:
Чтобы посмотреть индексы дбф-файлов без установки фоксов и иже с ним, можно воспользоваться отличным листер-плагином для тотала xBaseView, который может просматривать (а также печатать, искать, выполнять SQL запросы, импортировать и экспортировать БД) файлы практически всех БД.

П.С. Также может использоваться как автономная программа. Бесплатная версия имеет некоторые ограничения.
  

xbase.jpg ( 37 KB | Загрузки )
xbase.jpg
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #27 - 31. Августа 2007 :: 13:38
Печать  
И отдельно окно с индексами.
  

xbaseIND.jpg ( 31 KB | Загрузки )
xbaseIND.jpg
Наверх
 
IP записан
 
vip
1c++ power user
Отсутствует



Сообщений: 1570
Зарегистрирован: 19. Мая 2006
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #28 - 31. Августа 2007 :: 13:47
Печать  
JohnyDeath писал(а) 31. Августа 2007 :: 13:35:
Для счастливых обладателей TotalCommander'a:
Чтобы посмотреть индексы дбф-файлов без установки фоксов и иже с ним, можно воспользоваться отличным листер-плагином для тотала xBaseView, который может просматривать (а также печатать, искать, выполнять SQL запросы, импортировать и экспортировать БД) файлы практически всех БД.

П.С. Также может использоваться как автономная программа. Бесплатная версия имеет некоторые ограничения.


Для тех же счастливых обладателей TotalCommander'a (я к ним не отношусь, к Far'у привык) Улыбка
http://www.infostart.ru/profile/1329/projects/1053/
Автор - безусловный и многосторонний талант.
  
Наверх
ICQ  
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #29 - 31. Августа 2007 :: 13:59
Печать  
Да, хорошая штука (а лучша вот это), но тут тема немного другая - про индексы в ДБФ-базах.
Как я уже говорил,  xBaseView может использоваться как автономная программа. Так что сильно не расстраивайся!  Подмигивание
  
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #30 - 09. Ноября 2007 :: 15:39
Печать  
Полезный проект http://fox.wikis.com/wc.dll?Wiki~FoxProWiki
  
Наверх
ICQ  
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #31 - 11. Февраля 2008 :: 11:44
Печать  
Часть 3.
При использовании индексов Fox осталась последняя проблема -
соединение нескольких таблиц по индексу.

Например, в результате подзапроса выбрали документы расходные накладные,
и хотелось бы присоединить их табличные части.

У Таблицы "Документ (Мн.ч.) РасходнаяНакладная" , как и у всех таблиц табличных частей
есть индекс
Цитата:
I=IDLINE   |of IDDOC+LineN

или в терминологии Fox
Код
Выбрать все
iddoc+STR(lineno,4) 



Так как значение поля lineno неизвестно - соединиться с использованием индекса не удастся.
Особенно важно это для регистров , где таблица движений имеет индекс
Цитата:
iddoc+STR(lineno,4)+STR(actno,6)


К счастью Fox позволяет выполнять соединение по части строк.
Но чтобы такое соединение заработало нужно выполнить код
Код
Выбрать все
ОлеДБКоманда = глОлеДБ.СоздатьКоманду();
ОлеДБКоманда.Выполнить("EXECSCRIPT('SET ANSI OFF')"); 


Наиболее подходящим местом которой - после создания объекта OLEDBData

Описание команды :
Цитата:
SET ANSI ON | OFF

Параметры
ON

Короткие символьные строки дополняются справа пробелами или нуль-символами (0) для уравнивания их с более длинными символьными строками или выражениями. Когда SET ANSI установлено в ON,  обе сравниваемые символьные строки должны иметь одинаковую длину.

OFF

(По-умолчанию) Определяет, что короткие символьные строки не дополняются справа пробелами или нуль-символами (0) в целях уравнивания длин сравниваемых строк. Когда SET ANSI установлено в OFF,  две символьные строки сравниваются символ за символом по достижению конца короткой строки.

Т.е. это нужно учесть, если есть запросы, где могут использоваться поля разной длины
(для выборок полей это невозможно) Если в запросе вдруг понадобится все таки использовать полное
сравнение достаточно вместо "=" писать "==" (двойное сравнение)

После этого легко соединяться по индексу, для этого в левой части
выражения соединения (после ON) должно идти полное выражение индекса, а справа -
выражение по которому соединяемся

Пример
Код
Выбрать все
|SELECT  
|   ДокРасходнаяНакладная.Iddoc
|  ,$ТаблЧастьРасходнаяНакладная.Товар
|
| FROM
|
| $Документ.РасходнаяНакладная as ДокРасходнаяНакладная  
|    
| LEFT JOIN  $ДокументСтроки.РасходнаяНакладная as ТаблЧастьРасходнаяНакладная  
|  ON асходнаяНакладная.Iddoc
|
|  	WHERE ДокРасходнаяНакладная.iddoc =:ВыбРасход
|
// Используется 2 индекса
// 1. в секции Where - iddoc в таблице журнала
// 2. в секции JOIN - iddoc+STR(lineno,4) индекс таблицы ДокументСтроки.РасходнаяНакладная
  



Итого : время выполнения  0.002с

В секции JOIN есть строка Цитата:
ТаблЧастьРасходнаяНакладная.iddoc+STR(ТаблЧастьРасходнаяНакладная.lineno,4) = ДокРасходнаяНакладная.Iddoc

(Здесь плюсы - строковое сложение)
Т.к. стоит установка ANSI OFF то левое выражение будет обрезано до размера правого выражения ,
т.е. до ТаблЧастьРасходнаяНакладная.iddoc. Таким образом, это условие полностью эквивалентно -
Цитата:
ТаблЧастьРасходнаяНакладная.iddoc=ДокРасходнаяНакладная.Iddoc
, а дополнение после "+" пишется только для того, чтобы Fox понял что нужно использовать индекс.

При
Код
Выбрать все
|LEFT JOIN  $ДокументСтроки.РасходнаяНакладная as ТаблЧастьРасходнаяНакладная  
|	  ON ТаблЧастьРасходнаяНакладная.iddoc=ДокРасходнаяНакладная.Iddoc 



Время выполнения 0.129с
Разница 50 раз. При многопользовательском режиме еще больше.

Т.е. грубо говоря, можно придерживаться следующего простого правила :
для того, чтобы Fox использовал индекс нужно
составить обычный запрос  - как для SQL ,
но только в предложениях WHERE, JOIN - левое выражение дополнять до индекса, который хотим использовать.
И предварительно задать SET ANSI OFF


Можно проверить - оптимизирован ли Ваш запрос для выполнения vfpoledb.
Для этого получаем текстовый вид запроса для Fox : Цитата:
глМД = СоздатьОбъект("MetaDataWork");
ТекстЗапросаДляFoxPro=глМД.ОбрМетаСКЛ(ТекстЗапроса);

Выполняем. Если запрос оптимизирован в отдельном окне будет написано Rushmore optimization FULL
или соотвественно NONE
« Последняя редакция: 20. Марта 2008 :: 14:19 - kiruha »  
Наверх
 
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #32 - 11. Апреля 2008 :: 17:37
Печать  
Содержимое данного сообщения было перенесено СЮДА.
  
Наверх
www  
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #33 - 18. Августа 2009 :: 03:45
Печать  
kiruha писал(а) 11. Февраля 2008 :: 11:44:
Выполняем. Если запрос оптимизирован в отдельном окне будет написано Rushmore optimization FULL
или соотвественно NONE

А можно подробнее, где именно это будет написано. Попробовал - результат рабоыт метапарсера вижу, а вот про оптимизацию ни слова ...
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


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

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #34 - 18. Августа 2009 :: 04:36
Печать  
Dmitry The Wing писал(а) 18. Августа 2009 :: 03:45:
kiruha писал(а) 11. Февраля 2008 :: 11:44:
Выполняем. Если запрос оптимизирован в отдельном окне будет написано Rushmore optimization FULL
или соотвественно NONE

А можно подробнее, где именно это будет написано. Попробовал - результат рабоыт метапарсера вижу, а вот про оптимизацию ни слова ...

Заводи новую тему!
Эта ветка только для FAQ.
  

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


1C++ rocks!

Сообщений: 1
Зарегистрирован: 18. Апреля 2012
Re: Тема Использование индексов (ДБФ) часть 2.
Ответ #35 - 18. Апреля 2012 :: 03:09
Печать  
   Люди добрые! Подскажите пож-та. При открытии базы под FoxPro появилась ошибка "The 'VFPOLEDB.1' provider is not registered on the local machine". Скажите, как регистрировать данный dll?
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать