Табличка в базе FB 1.5 имеет порядка нескольких сотен тысяч записей. Подключение через ADO (IBProvider v3 Free) к табличке с клиентским курсором занимает несколько минут и пару сотен мегабайт памяти, затем память освобождается. Разумеется с серверным курсором такого не происходит, но в результате имеем гораздо меньшую скорость записи строк в таблицу, примерно в два раза
Что можете посоветовать в данном случае? Где можно покрутить чтобы ускорить подключение к табличке с клиентским курсором?
Здравствуйте, _avp_, Вы писали:
__>Табличка в базе FB 1.5 имеет порядка нескольких сотен тысяч записей. Подключение через ADO (IBProvider v3 Free) к табличке с клиентским курсором занимает несколько минут и пару сотен мегабайт памяти, затем память освобождается. Разумеется с серверным курсором такого не происходит, но в результате имеем гораздо меньшую скорость записи строк в таблицу, примерно в два раза __>Что можете посоветовать в данном случае? Где можно покрутить чтобы ускорить подключение к табличке с клиентским курсором?
А точно нужны все записи таблицы? Просто из поста не понятно, что с ними потом делается. Может попытаться ограничить набор данных.... Подумать бы в этом направлении. Если показывать- то не все, если обрабатывать, то обработать массово на серваке.
Здравствуйте, hun, Вы писали:
hun>А точно нужны все записи таблицы? Просто из поста не понятно, что с ними потом делается. Может попытаться ограничить набор данных.... Подумать бы в этом направлении. Если показывать- то не все, если обрабатывать, то обработать массово на серваке.
а кто сказал что выгружаю все записи? даже не показываю. речь идет о простом открытии таблички как cmdTable с ClientCursor, которое приводит к тому что ADO-провайдер начинает перетряхивать всю таблицу
__>а кто сказал что выгружаю все записи? даже не показываю. речь идет о простом открытии таблички как cmdTable с ClientCursor, которое приводит к тому что ADO-провайдер начинает перетряхивать всю таблицу
Можете пояснить, что значит "речь идет о простом открытии таблички как cmdTable с ClientCursor". Или кусочек кода покажите что-ли.
Если что-то приводит к тому, что "ADO-провайдер начинает перетряхивать всю таблицу" — то выкиньте это что-то.
iT>Можете пояснить, что значит "речь идет о простом открытии таблички как cmdTable с ClientCursor". Или кусочек кода покажите что-ли. iT>Если что-то приводит к тому, что "ADO-провайдер начинает перетряхивать всю таблицу" — то выкиньте это что-то.
А что, собственно, не устраивает? Негласный закон "скорость работы с данными прямо пропорциональна объему отжираемой оперативной памяти" никто не отменял, здесь он проявился во всей своей красе. Так что либо тащить записи в оперативку клиента все кучей (быстро, но памяти съест много), либо выдергивать их кусками и обрабатывать по одной. Правда есть еще вариант поправить что-то в консерватории (например перенести обработку на сервер), но не зная, что именно делается потом с полученными данными — копать в этом направлении имхо будет сложно.
Здравствуйте, Пацак, Вы писали:
П>А что, собственно, не устраивает? Негласный закон "скорость работы с данными прямо пропорциональна объему отжираемой оперативной памяти" никто не отменял, здесь он проявился во всей своей красе. Так что либо тащить записи в оперативку клиента все кучей (быстро, но памяти съест много), либо выдергивать их кусками и обрабатывать по одной. Правда есть еще вариант поправить что-то в консерватории (например перенести обработку на сервер), но не зная, что именно делается потом с полученными данными — копать в этом направлении имхо будет сложно. П>
клиентский курсор необходим поскольку в табличку пишется за раз большое кол-во записей, при серверном курсоре скорость записи на порядок ниже. как вариант решения — пришлось отдельно открывать запрос к этой таблице с клиентским курсором при условии ID=0, и добавлять записи уже в него.
Здравствуйте, _avp_, Вы писали:
__>Здравствуйте, Пацак, Вы писали:
__>клиентский курсор необходим поскольку в табличку пишется за раз большое кол-во записей, при серверном курсоре скорость записи на порядок ниже. как вариант решения — пришлось отдельно открывать запрос к этой таблице с клиентским курсором при условии ID=0, и добавлять записи уже в него.
Зачем тебе курсор, если нужно просто добавлять записи?! Просто добавь их, через insert
Привет, _avp_!
Вы пишешь 14 декабря 2006:
a> клиентский курсор необходим поскольку в табличку пишется за раз большое кол-во записей, a> при серверном курсоре скорость записи на порядок ниже.
Здравствуйте, _avp_, Вы писали:
__>клиентский курсор необходим поскольку в табличку пишется за раз большое кол-во записей, при серверном курсоре скорость записи на порядок ниже. как вариант решения — пришлось отдельно открывать запрос к этой таблице с клиентским курсором при условии ID=0, и добавлять записи уже в него.
Что вы делаете с этими данными, нужны ли вам все эти записи на клиенте? Если вы действительно используете все эти данные и читаете все поля во всех записях, то особой разницы в скорости для клиентского и серверного курсора нет. Клиентский курсор дольше грузится, зато потом данные быстро читаются. Серверный открывается мгновенно, но будут тормоза при чтении. Суммарно клиентский курсор будет даже быстрее, поскольку будет грузить данные большими блоками, а не запрашивать каждую запись отдельно.
Тяжело решать задачу не зная ее условий. По считанным строкам происходит какой-то расчет и потом запись в базу? Может не серваке считать? Тогда может и не надо будет никаких курсоров открывать....
Запомни несколько простых правил по работе с компонентами xxxTable:
1. Никогда не используйте компоненты xxxTable!
2. Никогда не используйте компоненты xxxTable
3. НИКОГДА, ^$#&*%, НЕ ИСПОЛЬЗУЙТЕ, ^%$%$#*, ЭТИ *&%&^$%#$$% xxxTable!!!
Именно xxxTable при открытии тащит всю таблицу на клиента.
Используй xxxQuery и xxDataSet.
Если мне память не изменяет, они именно так называются, просто на Delphi не писал уже лет 5.
Здравствуйте, algol, Вы писали:
A>Серверный открывается мгновенно, но будут тормоза при чтении. Суммарно клиентский курсор будет даже быстрее, поскольку будет грузить данные большими блоками, а не запрашивать каждую запись отдельно.
Да неужели А вы не просветите тёмного, что из себя, в контексте взаимодействия с FB, представляет серверный курсор?
PS. Ничто не мешает через IBProvider открыть двунаправленный "серверный" курсор и заставить его сразу загрузить все множество — просто вызовите MoveLast. Ничто, кроме ADOExpess, который не рюхает восьмибайтные закладки рядов, используемые в Free IBProvider v3. Хотя, если отказаться от произвольного доступа к множеству через закладки, ADOExpress помехой не будет. В конечно итоге получаем поведение очень похожее на "клиентский" курсор и не выжирающее оперативную память.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Да неужели А вы не просветите тёмного, что из себя, в контексте взаимодействия с FB, представляет серверный курсор?
Т.е. вы намекаете, что в IBProvider есть какие-то особенности реализации, отличающие его от нормальных провайдеров? Так расскажите нам.
КД>PS. Ничто не мешает через IBProvider открыть двунаправленный "серверный" курсор и заставить его сразу загрузить все множество — просто вызовите MoveLast.
Куда загрузить, на клиента? А он вас об этом просил? Он попросил только последнюю запись, вот ее ему и отдайте.
КД>В конечно итоге получаем поведение очень похожее на "клиентский" курсор и не выжирающее оперативную память.
В чем заключается похожесть? Вы хотите сказать, что ваш серверный курсор обеспечивает такую же скорость прокрутки и доступа к данным, как и клиентский? В ваших словах какое-то противоречие. С одной стороны — MoveLast грузит все множество. С другой стороны — не выжирается оперативная память. Так где же хранится ваше загруженное множество — в биополе?
Я еще раз повторю первоначальную мысль. Если нам нужно прочитать и обработать все записи, то независимо от типа курсора нам нужно: 1) получить данные с сервера БД, 2) передать их на клиента, 3) предоставить доступ к этим данным, преобразовав при необходимости типы. Серверный курсор создает иллюзию быстродействия, поскольку быстро открывается. Но доступ к данным будет медленнее, поскольку каждый раз будет запрашиваться и передаваться с сервера новый блок данных. Клиентский курсор долго открывается, поскольку загружает все данные, но обеспечивает быстрый доступ, поскольку данные уже на клиенте. В итоге временные затраты будут соизмеримы.
Здравствуйте, algol, Вы писали:
A>Т.е. вы намекаете, что в IBProvider есть какие-то особенности реализации, отличающие его от нормальных провайдеров? Так расскажите нам.
Его написал я
КД>>PS. Ничто не мешает через IBProvider открыть двунаправленный "серверный" курсор и заставить его сразу загрузить все множество — просто вызовите MoveLast.
A>Куда загрузить, на клиента? А он вас об этом просил?
Насчет первого вопроса — да, на клиента. На второй вопрос я отвечу вопросом — а он читал документацию по FB/IB и IBProvider'у ?
A>Он попросил только последнюю запись, вот ее ему и отдайте.
Дык я ему её и отдам. В конечном итоге.
КД>>В конечно итоге получаем поведение очень похожее на "клиентский" курсор и не выжирающее оперативную память.
A>В чем заключается похожесть? Вы хотите сказать, что ваш серверный курсор обеспечивает такую же скорость прокрутки и доступа к данным, как и клиентский?
Даже быстрее. Потому что клиентский курсор — это (грубо говоря) OLEDB провайдер над OLEDB провайдером.
A>В ваших словах какое-то противоречие. С одной стороны — MoveLast грузит все множество. С другой стороны — не выжирается оперативная память. Так где же хранится ваше загруженное множество — в биополе?
Точно
Этим IBProvider и отличается от всех остальных компонент доступа. Не только к FB/IB.
A>Если нам нужно прочитать и обработать все записи, то независимо от типа курсора нам нужно: A>1) получить данные с сервера БД, A>2) передать их на клиента, A>3) предоставить доступ к этим данным, преобразовав при необходимости типы.
Насчет третьего — в случае IBProvider'а достаточно попросить предоставить данные в нужном виде. В нем реализован достаточно сильный конвертор типов.
A>Серверный курсор создает иллюзию быстродействия, поскольку быстро открывается.
Он работает быстро не потому что "серверный", а потому что IB/FB фактически откладывает выполнение запроса до первого фетча. Провайдер, когда ему говорят выполнить "execute", делает только execute.
A>Клиентский курсор долго открывается, поскольку загружает все данные, но обеспечивает быстрый доступ, поскольку данные уже на клиенте. В итоге временные затраты будут соизмеримы.
Если не считать пересылку данных из "серверного" курсора в "клиентский".
-------
Вы слишком буквальное восприятие слов "клиентский" и "серверный" курсоры. Клиентский курсор был для чего придуман? Если не принимать во внимание концепцию отключенных рекордсетов. Для того что бы прозрачно наращивать функционал убогих OLEDB провайдеров, которые способны предоставлять только forward-only курсоры. IBProvider в такой помощи не нуждается.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Его написал я
Често говоря, догадывался.
A>>Он попросил только последнюю запись, вот ее ему и отдайте. КД>Дык я ему её и отдам. В конечном итоге.
То есть если мне интересно получить только одну последнюю последнюю запись, вы мне в нагрузку передадите по сети и все остальные?
КД>Даже быстрее. Потому что клиентский курсор — это (грубо говоря) OLEDB провайдер над OLEDB провайдером.
Т.е. ваш серверный курсор — это фактически клиентский, только реализован средствами провайдера, а не Client Cursor Engine? А где же тогда экономия памяти? И как насчет поддержки dynamic и key-set курсоров?
A>>В ваших словах какое-то противоречие. С одной стороны — MoveLast грузит все множество. С другой стороны — не выжирается оперативная память. Так где же хранится ваше загруженное множество — в биополе? КД>Точно КД>Этим IBProvider и отличается от всех остальных компонент доступа. Не только к FB/IB.
И все-таки интересно, где вы храните данные на клиенте, если не используете оперативную память.
КД>Он работает быстро не потому что "серверный", а потому что IB/FB фактически откладывает выполнение запроса до первого фетча. Провайдер, когда ему говорят выполнить "execute", делает только execute.
В случае открытия таблицы это не принципиально.
КД>Если не считать пересылку данных из "серверного" курсора в "клиентский".
Пересылка данных с серверной машины на клиентскую будет в любом случае.
КД>Вы слишком буквальное восприятие слов "клиентский" и "серверный" курсоры.
Я это понимаю в первую очередь как значение свойства CursorLocation, а во вторую — как место хранения данных.
КД>Клиентский курсор был для чего придуман? Если не принимать во внимание концепцию отключенных рекордсетов. Для того что бы прозрачно наращивать функционал убогих OLEDB провайдеров, которые способны предоставлять только forward-only курсоры. IBProvider в такой помощи не нуждается.
Здравствуйте, algol, Вы писали:
A>>>Он попросил только последнюю запись, вот ее ему и отдайте. КД>>Дык я ему её и отдам. В конечном итоге.
A>То есть если мне интересно получить только одну последнюю последнюю запись, вы мне в нагрузку передадите по сети и все остальные?
Да. Увы и ах. Я не замарачивался с оптимизации под любые ваши хотения.
КД>>Даже быстрее. Потому что клиентский курсор — это (грубо говоря) OLEDB провайдер над OLEDB провайдером.
A>Т.е. ваш серверный курсор — это фактически клиентский, только реализован средствами провайдера, а не Client Cursor Engine?
Угу.
A>И как насчет поддержки dynamic и key-set курсоров?
А что такое dynamic и key-set курсоры? Извини, но я как-то не замарачиваюсь на ADO и его терминах. В основном юзаю только forward-only курсоры.
Провайдер поддерживает три вида честной навигации:
— однонаправленный
— двунаправленный
— произвольный доступ через закладки (key-и?)
Нечестная, это когда клиент удерживает идентификаторы рядов (HROW) и моделирует через них произвольный доступ. В ADO это можно сделать, установив свойство CacheSize в очень большое значение.
В общем случае — HROW<>закладке
A>>>Так где же хранится ваше загруженное множество — в биополе?
A>И все-таки интересно, где вы храните данные на клиенте, если не используете оперативную память.
Я про пересылку данных из моего провайдера в то, что вы называете "клиентским" курсором.
КД>>Вы слишком буквальное восприятие слов "клиентский" и "серверный" курсоры.
A>А batch update вы тоже сами поддерживаете?
Да. Но фичи с обновляемыми множествами доступны только в IBProvider v2. Подробности я постарался описать в вышеуказанном документе.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --