У нас есть приложение, которое использует OCI, но мы не можем заставить предварительную загрузку работать.
У нас есть запрос на выборку для таблицы с дюжиной столбцов (среди них один столбец CLOB и один MDSYS.GEOMETRY
колонка). Столбец CLOB в 99% случаев меньше 4000 байтов и даже в 50% случаев пуст.
Процесс выглядит следующим образом:
OCI_ATTR_PREFETCH_ROWS
до 500OCI_ATTR_LOBPREFETCH_SIZE
до 8000OCISTMTEXECUTE
с iters 1, поскольку одна строка извлекается в буфер. Теперь, если мы посмотрим на WireShark, мы увидим, что сетевые пакеты никогда не заполняются (есть только одна запись на одну передачу).
Если мы выполним тот же запрос выбора с SQLDeveloper, то пакеты будут хорошо заполнены, поэтому мы можем предположить, что предварительная выборка строк должна работать.
Что нам здесь не хватает?
Так как я недавно столкнулся с той же проблемой:
OCI_ATTR_PREFETCH_ROWS
а также OCI_ATTR_LOBPREFETCH_SIZE
не работайте вместе
Предварительная выборка не действует, если столбцы LONG, LOB или Opaque Type (например, XMLType) являются частью запроса.
Всякий раз, когда у вас есть большие объекты в наборе результатов, вы не можете использовать неявную предварительную выборку через OCI_ATTR_PREFETCH_ROWS, и вместо этого вам нужно использовать явную выборку строки, вызывая OCIStmtFetch2 () с rowcount> 1.
Затем, конечно, вам нужно заранее настроить буферы, отследить уже использованные строки и, в особенности, вызвать функцию OCIDefineArrayOfStruct (), чтобы сообщить оракулу о вашем расположении буфера.