Как стать автором
Обновить

Delphi+PostgreSQL

Время на прочтение2 мин
Количество просмотров25K
В одном из проектов понадобилось получить доступ к БД PostgreSQL из Delphi и, в частности, читать BLOB поля из этой БД. Разумеется, дабы не изобретать велосипед, решил поискать готовые компоненты. Нашлось два решения:

-бесплатное. ZeosLib.
-платное. PostgresDAC.

Производительность была ключевым моментом, поэтому я решил их сравнить.

Тестирование производилось на базе PostgreSQL 8.2.5, в обоих компонентах использовалась dll той же версии. Предварительно запрос был выполнен пару раз, для того, чтобы база его закэшировала.

В скобках указано усреднённое значение для следующих трёх попыток, которые были выполнены без закрытия программы. Запрос был вида «select * from table», где table — таблица с 450 тысячами неодинаковых записей, не обработанная с помощью vacuum. Позиционирование представляло из себя код:

Query.First;
repeat
Query.Next;
until Query.Eof;

Результаты:

PostgresDAC
Соединение с базой: 170 мс (65 мс)*.
Выполнение запроса: 5900 мс (5900 мс).
Позиционирование: 4150 мс (4150 мс)

ZeosLib
Соединение с базой: 60 мс (60 мс).
Выполнение запроса: 5200 мс (5200 мс).
Позиционирование: 8100 мс (1900 мс)

Но самое интересное, как оказалось, ждало меня дальше.
При попытке получить данные из BLOB поля, оба компонента возвращали nil. Недолгие и несложные эксперименты показали, что так происходит при превышении Binary Object'ом размера в 20 килобайт.

Гугл проблему решить не помог, пришлось браться за напильник самому. Я конвертировал libpq.h из поставки PostgreSQL в pas, при помощи замечательной утилиты и стал проверять.

Действительно, стандартная функция PQexec отдавала nil вместо данных. Проблема решилась только использованием асинхронного запроса.

Вот такой код, со стандартными функциями из libpq.dll, получает из базы поле BLOB любой длинны (разумеется, для этого нужен unit с определёнными функциями и предварительно установленное соединение myConnection):

PQsendQuery(myСonnection, pchar(myQuery));
myResult:=PQGetResult(myConnection);
buf:=PQunescapeBytea(PQgetvalue(myResult, 0, 0), resultKey);


PS: Первый мой топик на хабре. Надеюсь, написаное действительно кому-нибудь поможет.

PPS: Ах да, есть ещё способ доступа через ADO, но он по всем показателям где-то в 2-2,5 раза медленнее Zeos'а и DAC'а. Да и искал я именно специализированные компоненты, так что в тестах ADO не присутствует.
Теги:
Хабы:
+8
Комментарии12

Публикации

Истории

Работа

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн