Форум » LetoDB, HbNetio. » Leto DB Server (продолжение 8) » Ответить

Leto DB Server (продолжение 8)

Pasha: Немного доработал документацию к letodb

Ответов - 273, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 All

Pasha: Сейчас время актуальности skip и seek буфера - 1 секунда. Для медленного удаленного интернет-соединения это может быть недостаточно. Поэтому я добавил возможность задать это время: 5-й параметр leto_Connect

alkresin: Это время, как я понимаю, сейчас имеет одно значение для всех файлов ? Мне кажется, тут нужен более гибкий подход - возможность установки и общего значения, и - для каждой таблицы в отдельности. И должно быть значение, равное 0 как эквивалент бесконечности, т.е., чтобы это время актуальности было бесконечным. Я бы в своих приложениях ( пока это теоретическое предположение, поскольку у меня стоит пока старая версия, где этого времени нет вообще ) поставил бы общее значение 0 и, возможно, только для некоторых файлов какое-то фиксированное - например, 5 сек.

Pasha: Добавлю еще в LETOAREA это параметр, знаковый. -1 будет означать общую настройку для соединения, 0 - бесконечность. Для установки добавлю новую константу для dbInfo: DBI_XXX. Кстати, сейчас проверю, насколько поможет увеличение этого параметра для удаленного соединения.


alkresin: Этот -1 для LETOAREA должен быть, по идее, значением по умолчанию.

Pasha: Увеличение времени актуальности буфера немного помолго, но оказалось далеко не решающим фактором. Пришлось оптимизировать еще несколько действий. Включил использование seek-буфера там, где это необходимо, доработал его: теперь если dbSeek(xKey) возвращает .F., результат все равно сохраняется в seek-буфере и затем используется. Убрал несколько лишних операций. В результате количество запросов к серверу сократилось с 265 до 29-ти, т.е. почти на порядок.

alkresin: Отлично. А что это за seek-буфер ? Какие записи он хранит, тем более когда dbSeek возвращает .f. ?

Pasha: Я использую seek-буфер к примеру для выборки данных из небольшого справочника размером несколько десятков-сотен записей. Среди них есть как правило наиболее часто используемые. Определяю размер seek-буфера 20-30 записей вызовом leto_SetSeekBufer(20) При этом результат работы dbSeek: значение ключа и копия полученной с сервера записи будет сохранен в буфере, и при следующем вызове seek с тем же значением ключа запись будет браться из буфера без обращения к серверу. Вызов leto_SetSeekBufer без параметров вернет количество попаданий в буфер. А вчера я добавил сохранение в буфер ненайденной записи. Если будет еще раз seek с тем же значеним ключа, запись будет перемещена на eof() без запроса к серверу. Механизм примерно такой же, как и для skip-буфера. Можно использовать к примеру в случае использования set relation, или просто для dbSeek

Pasha: Меня спрашивают, что предпочтительнее по производительности, использование dbfcdx в терминалке или letodb ? А я не знаю, что ответить, так как сам терминал-сервер не использую. Кто может сказать, большой траффик получается в случае использования терминал-сервера windows ?

Andrey: Pasha пишет: Кто может сказать, большой траффик получается в случае использования терминал-сервера windows Я использую на нескольких фирмах терминал-сервера. Так как сервер для терминалов используют как правило более мощный, то задача с использованием обычного dbfcdx - просто летает.... Но по цене и простоте лучше использовать конечно LetoDb (экономим на обслуживание и настройке терминал-сервера windows ) !

PSP: Да, тут главное - цена. Терминальный сервер легально можно поднять только на MS Server 20xx. Про его цену вместе с лицензиями говорить не обязательно. Думаю, что вариант с терминалом будет побыстрее, особенно через интернет соединение, но и затраты несоизмеримо выше.

Vlad04: Есть платные терминалы , работают и на Win 7 64, других разработчиков, цены доступные

Vlad04: Но под терминалом не работает ADS local.

Pasha: Я давно косо смотрел на выборку из таблицы с использованием scope и filter. Для нее необходимо сделать несколько запросов: set scope set filter seek skip (один или несколько) clear scope clear filter Получается как минимум 6 запросов к серверу. Мне хотелось их минимизировать, до одного запроса.. Сначала возникла идея сделать обработку блоков команд. Но таких команд немного: set filter и set scope, и в конце концов я от этой идеи отказался. Но вопрос как-то решать надо. Решил использовать возможности skip-буфера: его заполнение одной командой и обработка результата на клиенте обычными вызовами навигационых функций. Я не стал добавлять новую команду для сервера, а сделал через механизм udf-функций, для которых есть аналогичный, но более гибкий интерфейс. Теперь вместо кода: set index to <indexname> set scopetop to <s1> set scopebottom to <s2> set filter to <f> go top while ! eof() ... skip enddo set scope to set filter to можно использовать код: leto_ParseRecords(leto_Udf('UDF_dbEval', <s1>, <s2>, <indexname>, <f>)) while ! eof() ... skip enddo Это делается одним запросом к серверу. Конечно, большую выборку надо использовать с осторожностью, поскольку вся она передается одним запросом. дока будет чуть позже.

alkresin: Дело хорошее! Leto_ParseRecords() - это новая функция, которая разбирает результат, присланный UDF_dbEval ?

Pasha: alkresin пишет: Leto_ParseRecords() - это новая функция, которая разбирает результат, присланный UDF_dbEval ? Да, именно так. Она заполняет skip-буфер (без ограничения на размер, сколько получится), и затем команды dbSeek(1) ... while ! eof() могут выбирать из него данные без обращения к серверу. Послу выборки желательно сбросить skip-буфер командой dbInfo(DBI_CLEARBUFFER) чтобы случайно командами skip(-1) не выбрать не те данные. Мне еще хочется в skip-буфере сделать такое изменение. Сейчас при обновлении данных он просто сбрасывается. Если обновлялись неиндексные поля текущей записи, можно это не делать, а прямо в буфере в поле флагов записи, которая обновилась, делать пометку, что именно эту запись из буфера брать не надо. Тогда skip-буфер можно быдет полноценно использовать при обновлении данных.

SergKis: alkresin пишет:Дело хорошее Дело ОЧЕНЬ ХОРОШЕЕ !!! А добавив aFields, можно и без вызова UDF работать, добавив возврат в буфере массива Recno записей выборки (для больших и неопределенных в объеме выборок), получится вариант SELECT ... ! И если такое добавить в версию LETO, собираемую xHabour - совсем ЗАМЕЧАТЕЛЬНО !

Pasha: Я вчера забыл сделать коммит для server.prg, там небольшое изменение - надо добавить request для leto_dbEval. Сегодня сброшу. Кстати, в mail dev list почему-то не проходят письма. А насчет aFields: я не очень понял, что имеется в виду. Можно подробнее ?

SergKis: Pasha пишет: А насчет aFields: я не очень понял, что имеется в виду. Можно подробнее ? Как я понял, сейчас в skip-буфере находится все поля записи. При помощи aFields := {"Field1", "Field10"} - только нужные.

Pasha: Добавить к UDB_dbEval еще один параметр aFields, что ли ? И передавать с сервера только значения тех полей, которые есть в этом массиве ? Тогда значения остальных полей будут пустыми, и в skip буфере, и при считывании записей. Конечно, для передачи даже пустых полей требуется один-два байта. Это можно сделать, но пользоваться таким запросом надо с осторожностью, понимая, что делаешь. Обращение к полям, которых нет в aFields, даст пустое значние, а ведь значение у них есть. Если в массиве не будет ключевых полей, то не получится вычисление ключевого выражения.

SergKis: Pasha пишет но пользоваться таким запросом надо с осторожностью Конечно - это для тех, кто понимает, что происходит ! Зато можно значительно уменьшить трафик в различных расчетах где символьные данные не нужны и т.д. и т.п. Еще можно добавить параметр .T./.F., что в skip буфере: записи с полями или ссылки на записи, участвующие в запросе и работать вместо skip через goto.



полная версия страницы