| |||
![]()
|
![]() ![]() |
![]()
Oracle: работа с LOB-ами через OCI. В СУБД Oracle есть встроенный тип данных под названием LOB (Large Object), что означает набор неструктурированной информации, текстовой (CLOB) или бинарной (BLOB) произвольного объёма. Речь пойдёт о том, как обеспечить приемлемое быстродействие операций чтения/записи при работе через интерфейс OCI. Создание таблицы с колонкой из LOB На этом этапе следует определить, потребуется ли встроенный кэш Oracle для чтения данных из LOB. Если собираетесь читать одни и теже данные несколько раз, то кэш имеет смысл использовать; скорость чтения некэшированного LOB-а очень мала. Ключевые слова -- CACHE/NOCACHE/CACHE READS. CACHE влияет и на чтение, и на запись, а CACHE READS -- только на чтение. Есть ещё ряд параметров, в меньшеё степени влияющих на быстродействие: LOGGING/NOLOGGING, PCTVERSION, ENABLE/DISABLE STORAGE IN ROW, о которых подробно рассказано в документации. Размер кэша определяется параметром базы db_cache_size .Запись (OCILobWrite()) Для многократных разбросанных записей следует включить CACHE, NOLOGGING и PCTVERSION 0; видимо, это всё, что можно сделать. Для многократной записи маленькими кусочками в конец LOB-а можно и нужно использовать буферизацию. С ней процесс становится быстрее, но и обработка ошибок гораздо «интереснее». Режим буферизации LOB-а включается вызовом OCILobEnableBuffering(). Интересно, что этого вызова нет ни в PL/SQL, ни в JDBC, ни в OCCI-обёртке. Есть только в C и (?) в Visual Basic. О недостатках режима буферизации: во-первых, запрещён ряд стандартных операций, например, нельзя узнать размер LOB-а или сделать «добавление в конец». Приходится сохранять размер до буферизации, после чего заниматься ручным подсчётом. Во-вторых, OCILobWrite() может возвращать ошибки:
И ещё один момент: OCILobWrite не обязан записывать сразу все данные, которые ему дали на вход. Количество записанных байт он возвращает, и надо дозаписывать снова, пока не кончится. Чтение (OCILobRead()) При многократном чтении следует включить CACHE либо CACHE READS. При последовательном чтении маленькими кусками можно включить буферизацию, но она работает менее эффективно, чем собственный рукодельный буфер. При использовании оного штатную буферизацию лучше выключить, она будет избыточна. То же самое, что и с записью: не стоит рассчитывать на то, что OCILobRead() прочтёт все данные за один раз. |
|||||||||||||
![]() |
![]() |