Страница 1 из 1

ODBC + CBuilder

Добавлено: 10 июн 2003, 19:49
АлексейН
Тема поднималась неоднократно и все знают, что надо писать на випе =), но все же интересно...

Вот делаю я запрос с помошью из Builder'a через ODBC, разультат - от десятка до тысячи строк. Я не спрашиваю почему этот запрос выполняется долго, мне инетерсно
что всё это время делает клиент(т.е. моя прога), если винт постоянно свопится в течение всего запроса(10-30 минут).
Я так понимаю, что всю обработку выполняет сервер и передает рез-ты мне, а я должен спокойно ждать. Но нет! Винт усерно жужжит
непонятно зачем. Что это???

Re: ODBC + CBuilder

Добавлено: 16 июн 2003, 10:07
Goblin
Это создается куча вспомогательных объектов в интерфейсе BDE->ODBC->Btrieve API, который твоя программа пользует, и который в память весь не влазит или система считает что их лучше в своп закинуть ... Если ты просто прошариваешься по таблице через TTable - это еще куда ни шло , а вот если пользуешь TQuery, у которого источником данных является ODBC-источник от Первасива(если еще и Первасив 7-ка - то вообще прелесть :( ), который не особо заточен под замечательные извраты SQL касаемо выборки,сортировки,группировки данных - то тут уж ничего не поделаешь ... Интерфейс неродной, да еще из-под подвыподверта приходится ходить : BDE-шные компоненты(не самые худые компоненты ) тянутся к "жирному" и медленному ODBC, который уже и лезет к родному API ... Чем дальше путь от кода обозначающего получение данных до низкоуровнего API получения данных , тем морда программы ширше и ползает она медленнее :)

Re: ODBC + CBuilder

Добавлено: 16 июн 2003, 11:34
АлексейН
Тогда такой вопрос.
Почему на соседней машине, где столько же памяти, только проц мощнее и сетка 100мБит против 10 на моем запросы выполняются без свопов и раз в 20-100 быстрее? ??? ???

Уточнение - BDE не используется, так как вместо TQuery есть TPvQuery.

Re: ODBC + CBuilder

Добавлено: 17 июн 2003, 05:50
OlleUp
Объясняю.
Сначала вопрос: а как работет клиент и сервер ?
Ответ: клиент отправляет серверу запрос на языке SQL, сервер выполняет его и высылает данные клиенту.
Вопрос: А как сервер высылает данные клиенту ?
Ответ: двумя способами: все немедленно и по требованию. Все немедленно означает, что клиент, хочет
или не хочет получает все результаты запроса, весь набор данных сразу, и, пока все не получит
дальше работать не будет. Так было когда-то. Сейчас везде рулит второй способ: по требованию.
Допустим, в результате запроса должно вернуться 100 записей. Сервер выполнил запрос,
подготовил в своих внутренних структурах данные для отправки и говорит клиенту: готово,
можешь забирать данные. Клиент говорит: ок, дай мне 10 записей.
С этого момента начинаются различия для разных SQL серверов.
Серверы, поддреживающие внутренние двунаправленные курсоры высылают клиенту 10 записей,
но помнят о них. Серверы, не поддреживающие такие курсоры высылают клиенту 10 записей и
забывают о них. Т.е. сейчас в кэше сервера лежит не 100 а 90 записей.
Пока большинство серверов не поддерживает внутренние двунаправленные курсоры.
Поэтому, если клиент захочет снова просмотреть первые 10 записей запроса он должен
сделать это сам, за счет своих механизмов.
Именно такой механизм реализует ODBC, впрочем, опционально.
ODBC выкачивает ВСЕ данные с сервера в свой кэш и закрывает сессию на сервере.
А уже потом ODBC может вернуть и количество полученных записей
(сервером эта функция не поддерживается) и бегать курсором взад-вперед.
Есть другой механизм - в кэш вычитывается не СРАЗУ все, а порциями, допустим по 50 записей.
Но если пользователь в таком механизме захочет получить кол-во записей, он этого не получит.
Если перейдет к концу таблицы - например по CNTRL-END, механизм будет вычитывать опять все - как и первый вариант.
У вас как раз это и происходит - ODBC кэширует запрошенные данные. На более быстром клиенте
процесс естественно идет быстрее.

Так примерно.
Хабаровск, Новый Атлант.