|
Что тормозит общение VFPOLEDB с фоксом: индексы, сеть или ..?
|
|||
---|---|---|---|
#18+
Для интеграции 1С и FoxPro (изменения в 1С должны быть отражены в Фоксе) я создал механизм прокси-объектов для работы с фоксом в контексте 1С. В результате все возможные операции чтения, записи, изменения и удаления у меня реализованы через подключение VFPOLEDB. Я использую следующий вариант подключения Код: sql 1. 2. 3. 4.
Далее, я преобразую обращение 1С в sql запрос и выполняю его через данное подключение. Понятно, что вся работа с таблицами фокса происходит на локальной машине, у меня есть мысли как вынести выполнение на сервер, но до этого еще далеко. Так вот, все работает вроде бы прекрасно, на локальных файлах. Но когда обращаюсь к базам расположенным в сети, время выполнения запроса вырастает в десятки раз. Подскажите, что может быть причиной? Может быть в строку подключения нужно добавить ряд параметров, необходимых для оптимизатора, может проблема в трафике или серверном железе. Индексы. Первая мысль была что у меня не используется индексные файлы, тем более программисты foxPro сами бояться использовать sql синтаксис, и используют исключительно внутренние механизмы типа SEEK. Но я эту мысль старательно отбрасываю, потому как новые записи у меня индексируются, а битый индекс (если вдруг найдется) сразу выдает ошибку. В ходе эксплуатации обнаружил еще одну проблемку: выполнение запроса через VFPOLEDB сильно грузит клиентскую машину и элементарный запрос типа select * from ... where .., возвращающий 200 записей может прерваться от нехватки памяти. Подскажите, пожалуйста, в чем может быть проблема? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2012, 14:03 |
|
Что тормозит общение VFPOLEDB с фоксом: индексы, сеть или ..?
|
|||
---|---|---|---|
#18+
1. FoxPro активно работает с кешем как индексов, так и собственно таблиц. Это значит, что при первом выполнении запроса кроме собственно выполнения происходит еще и кеширование данных на локальной машине. При повторном выполнении запроса время сократится на порядок. Для проверки дайте команду на выполнение запроса два раза подряд и замерьте время выполнения первого и второго раза. 2. Основа ускорения выполнения запросов - это индексы. Есть индексы - оптимизация (ускорение) возможно. Нет индексов - будет сканирование исходной таблицы. Т.е. медленно. Тот факт, что выборка возвращает 200 записей, не означает, что анализироваться будут те же 200 записей. Возможно, для отбора результата надо будет просканировать всю таблицу. И если ее размер несколько миллионов записей, то тормоза неизбежны. Чтобы сказать что-то определенное нужно видеть собственно запрос и знать какие именно индексы существуют у таблицы. Кроме всего прочего, если текущая кодовая страница среды FoxPro отличается от кодовой страницы таблиц (CODEPAGE) или отличается Collation у индексов, то для VFP9 индексы использоваться вообще не будут. Оптимизация невозможна. Уточните, какие кодовые страницы у таблиц DBF (866 или 1251) ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2012, 14:25 |
|
Что тормозит общение VFPOLEDB с фоксом: индексы, сеть или ..?
|
|||
---|---|---|---|
#18+
AleGolТак вот, все работает вроде бы прекрасно, на локальных файлах. Но когда обращаюсь к базам расположенным в сети, время выполнения запроса вырастает в десятки раз. Подскажите, пожалуйста, в чем может быть проблема? Скорость 100 мбитной сети примерно 10-11 мбайт в секунду максимум, скорость чтения с винта 80-90. Если данные закэшированы виндой - еще быстрее. Если есть какая большая база, то как вариант подумать на перевод ее под MS-SQL Server ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2012, 14:41 |
|
Что тормозит общение VFPOLEDB с фоксом: индексы, сеть или ..?
|
|||
---|---|---|---|
#18+
ВладимирМ1. FoxPro активно работает с кешем как индексов, так и собственно таблиц. Это значит, что при первом выполнении запроса кроме собственно выполнения происходит еще и кеширование данных на локальной машине. При повторном выполнении запроса время сократится на порядок. Все так если только один пользователь открыл файл, если двое и больше, то каждый раз будет все качаться. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2012, 14:42 |
|
Что тормозит общение VFPOLEDB с фоксом: индексы, сеть или ..?
|
|||
---|---|---|---|
#18+
Да, про 200 строк я сгоряча упомянул, я знаю как происходит выполнение запроса. По поводу кодировок -- видел Ваш давний пост. у меня такие результаты: ?CPDBF -- 866 ?IDXCOLLATE(здесь я ставлю порядковый номер индекса) возвращает MACHINE Кстати, заметил такую вещь, после выполнения запроса select * into cursor ... ?CPDBF стал возвращать 1251, а ?IDXCOLLATE вообще ничего не выдает По поводу моего запроса. Я его строю динамически. Например в select - where я обычно передаю только список однозначно определяющих полей. В таблице фокса индексов много, на все случаи жизни. Иногда мой список полей совпадает с одним из индексов, иногда избыточен или вообще иной. В случае insert и update я вынужден прописывать все поля таблицы, если нужно чтобы поле было пустое -- я передаю значение по умолчанию для соответствующего типа данных. Например для пустой даты я передаю CTOD('//'). Правильно ли я понимаю, что для того чтобы индекс использовался, например в select, нужно в условие подавать список полей, соответствующее одному из индексов? Но что тогда делать например с запросом insert? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2012, 14:53 |
|
Что тормозит общение VFPOLEDB с фоксом: индексы, сеть или ..?
|
|||
---|---|---|---|
#18+
AleGolПравильно ли я понимаю, что для того чтобы индекс использовался, например в select, нужно в условие подавать список полей, соответствующее одному из индексов? Но что тогда делать например с запросом insert? Надо конкретные примеры тормозящих запросов, тогда тебе конкретно ответят. В общих словах если требуется выборка каких-то конкретных значений поля, то при наличии индекса будет прочитан сам индекс (и то не полностью) и те записи которые содержат нужные значения. При отсутствии индекса - будет прочитана вся таблица. например Код: sql 1.
с индексом по Id произойдет чтение только тех записей где Id = 10, без индекса - вся таблица будет скопирована с сервера на клиента. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2012, 15:08 |
|
Что тормозит общение VFPOLEDB с фоксом: индексы, сеть или ..?
|
|||
---|---|---|---|
#18+
Dima T, Спасибо. проверю свои запросы на соответствие индексам. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2012, 15:15 |
|
Что тормозит общение VFPOLEDB с фоксом: индексы, сеть или ..?
|
|||
---|---|---|---|
#18+
Если кодовая страница файлов DBF = 866, то попробуйте в строке подключения добавить парамер CODEPAGE=866 Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
VFPOLEDB был создан именно для VFP9. Поэтому на него распространяются ограничения этой версии. Сам возможность использования индексов для оптимизации включается только если кодовая страница файла DBF совпадает с кодовой страницей среды. В данном случае под "средой" следует понимать установленное соединение Если это не поможет, то попробуйте после установки соединения дать такую команду Код: sql 1.
Но это без гарантий, поскольку в оригинальной версии (до Service Pack) такое понижение не включало индексов созданных в другой кодовой страницы в оптимизацию. Не в курсе, распространяется ли Service Pack на VFPOLEDB. Ну и кроме того, такое понижение отбрасывало ряд возможностей в синтаксисе команды Select-SQL AleGolПравильно ли я понимаю, что для того чтобы индекс использовался, например в select, нужно в условие подавать список полей, соответствующее одному из индексов? Не так. В условии WHERE надо использовать конструкции, которые были использованы при создании индексов. Например, если индекс был создан на основе конструкции F1+F2, то в WHERE надо написать F1+F2 = (...). А вот F1 = (...) индекс использовать уже не будет, если только не существует индекса созданного напрямую по выражению F1 AleGolНо что тогда делать например с запросом insert? А что, у Вас и insert тормозит? Или Вы и там используете WHERE? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.08.2012, 15:28 |
|
Что тормозит общение VFPOLEDB с фоксом: индексы, сеть или ..?
|
|||
---|---|---|---|
#18+
ВладимирМ, Спасибо, помогла именно кодировка. условие where пока не критично, но на случай сложной таблицы буду оптимизировать по составу индексов. Я не совсем понял, что значит F1+F2 = (...) Допустим у нас есть таблица, колонки С1, С2, С3, С4. Есть индексы С1, назовем его I1 и С1 + С2 - соответственно I2. Имена индексов в случае sql запроса к драйверу бесполезны. говоря, что необходимо ориентироваться на состав индексов при составлении запроса, я имел ввиду следующее. Если у нас условие С1 = 1 И С3 = 1, то я так составляю запрос where (C1=1) and (C3 = 1). Если условие С1 = 1, С2 = 1 и С3 = 1, то запрос where ((C1=1) and (C2=1)) and (C3 = 1). На самом деле по ANSI условие where должно читаться и применяться справа налево, но похоже оптимизатор vfp9 на это не смотрит, т.е. порядок не важен. Поэтому скобки которые я наставил - они лишние. В дальнейшем я хочу добавить обработку условий or, not, операции сравнения, и вот для этого случая я хочу чтобы мой механизм добавлял скобки в соответствии с индексами. А что имели ввиду Вы? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.08.2012, 13:54 |
|
Что тормозит общение VFPOLEDB с фоксом: индексы, сеть или ..?
|
|||
---|---|---|---|
#18+
Последний пример я не совсем корректно привел. Хотел написать так Код: sql 1.
Это я к тому, что сперва проверяем фильтруем по максимальному индексу, потом применяем последующие после чего пишем оставшееся условие по которому индекса не существует (если оно есть), ... |
|||
:
Нравится:
Не нравится:
|
|||
09.08.2012, 13:58 |
|
Что тормозит общение VFPOLEDB с фоксом: индексы, сеть или ..?
|
|||
---|---|---|---|
#18+
AleGolЯ не совсем понял, что значит F1+F2 = (...) А что имели ввиду Вы? Есть индекс I1 построенный по полю С1 Есть индекс I2 построенный по выражению С1 + С2 Если написать WHERE C1=1 and C2 = 1, то будет использован только и исключительно индекс I1 построенный по полю С1. По условию C2 = 1 никакого индекса использовано не будет. Частичная оптимизация. Если написать WHERE C1+С2=2, то будет использован только и исключительно индекс I2 построенный по выражению С1 + С2 Если написать WHERE C2 = 1, то вообще никакого индекса использовано не будет, поскольку нет индексов, выражение которых совпадает с С2. Нет оптимизации. Другими словами, используются только и исключительно те индексы, выражение которых полностью совпадает с выражением, стоящим перед символом сравнения в директиве WHERE запроса. Разумеется, могут быть использовано и несколько индексов. Например, если написать WHERE C1=1 and С1+C2 = 2, то могут быть использованы оба индекса. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.08.2012, 15:03 |
|
|
start [/forum/topic.php?fid=41&fpage=53&tid=1583516]: |
0ms |
get settings: |
7ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
52ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
42ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 145ms |
0 / 0 |