Start · Sprachen · PHP · Referenz · oci_set_prefetch_lob

oci_set_prefetch_lob

Funktion

Setzt die Datenmenge in Bytes, die Oracle für jedes CLOB oder BLOB beim Vorladen (Prefetch) überträgt, um Roundtrips zur Datenbank zu minimieren.

seit PHP 8.2.0 Kategorie: db

Signatur

oci_set_prefetch_lob(resource $statement, int $prefetch_lob_size): bool

Beschreibung

oci_set_prefetch_lob konfiguriert, wie viele Bytes eines LOB-Wertes (CLOB oder BLOB) Oracle bereits beim initialen Abruf einer Ergebnismenge zusammen mit den Zeilendaten überträgt. Ohne diese Einstellung muss für jeden LOB-Wert ein separater Roundtrip zur Datenbank stattfinden, was bei vielen Zeilen mit LOB-Spalten zu erheblichem Performance-Overhead führt.

Der Mechanismus arbeitet zusammen mit oci_set_prefetch, das die Anzahl vorab geladener Zeilen steuert. Wenn die LOB-Werte klein genug sind und vollständig in den konfigurierten Puffer passen, werden sie vollständig in einem einzigen Netzwerk-Roundtrip übertragen. Sind die LOBs größer als der Puffer, wird nur der konfigurierte Anfangsteil vorab geladen; der Rest wird bei Bedarf nachgeladen.

Die Funktion muss nach oci_parse, aber vor oci_execute aufgerufen werden. Ein sinnvoller Wert hängt von der durchschnittlichen Größe der LOB-Daten ab – typische Werte liegen zwischen wenigen Kilobytes und einigen Megabytes. Zu große Werte verschwenden Speicher bei kleinen LOBs, zu kleine Werte eliminieren den Performance-Gewinn nicht vollständig.

Diese Funktion ist besonders nützlich bei Abfragen, die viele Zeilen mit LOB-Spalten zurückgeben, z. B. beim Abruf von Dokumenten, Bilddaten oder großen Textspalten aus einer Oracle-Datenbank.

Parameter

Name Typ Default Beschreibung
$statement Pflicht resource Ein gültiges OCI-Statement-Handle, das zuvor mit oci_parse erstellt wurde und noch nicht ausgeführt wurde.
$prefetch_lob_size Pflicht int Die maximale Anzahl von Bytes, die pro LOB-Wert beim Prefetch übertragen werden. Ein Wert von 0 deaktiviert das LOB-Prefetching. Empfohlene Werte liegen typischerweise zwischen 1024 (1 KB) und mehreren Megabytes.

Rückgabewert

Typ
bool
Beschreibung
Gibt true bei Erfolg zurück, false bei einem Fehler (z. B. wenn das Statement-Handle ungültig ist oder die Funktion vor oci_parse aufgerufen wird).

Beispiele

LOB-Prefetch für eine einfache Abfrage aktivieren

<?php
$conn = oci_connect('hr', 'geheim', 'localhost/XE');
if (!$conn) {
    $e = oci_error();
    trigger_error(htmlspecialchars($e['message']), E_USER_ERROR);
}

$sql = 'SELECT employee_id, resume_clob FROM employees WHERE department_id = :dept';
$stmt = oci_parse($conn, $sql);

// LOB-Prefetch auf 256 KB setzen, bevor die Abfrage ausgeführt wird
oci_set_prefetch_lob($stmt, 262144);

// Zeilenweise Vorladung ebenfalls optimieren
oci_set_prefetch($stmt, 100);

oci_bind_by_name($stmt, ':dept', $dept_id);
$dept_id = 50;

oci_execute($stmt);

while ($row = oci_fetch_assoc($stmt)) {
    $clob_data = $row['RESUME_CLOB']->load();
    echo 'Mitarbeiter ' . $row['EMPLOYEE_ID'] . ': ' . strlen($clob_data) . " Bytes\n";
}

oci_free_statement($stmt);
oci_close($conn);
?>
Mitarbeiter 101: 4823 Bytes Mitarbeiter 102: 3109 Bytes ...

LOB-Prefetch deaktivieren (Wert 0)

<?php
$conn = oci_connect('hr', 'geheim', 'localhost/XE');

$sql = 'SELECT id, bild_blob FROM produktbilder WHERE kategorie = :kat';
$stmt = oci_parse($conn, $sql);

// Prefetch explizit deaktivieren, z. B. bei sehr großen BLOBs
// um Speicherverbrauch zu kontrollieren
$result = oci_set_prefetch_lob($stmt, 0);
if ($result === false) {
    echo "Fehler beim Setzen des LOB-Prefetch.\n";
} else {
    echo "LOB-Prefetch erfolgreich deaktiviert.\n";
}

oci_bind_by_name($stmt, ':kat', $kat);
$kat = 'elektronik';
oci_execute($stmt);

while ($row = oci_fetch_assoc($stmt)) {
    // BLOBs werden bei Bedarf direkt aus der DB geladen
    file_put_contents('/tmp/bild_' . $row['ID'] . '.jpg', $row['BILD_BLOB']->load());
}

oci_free_statement($stmt);
oci_close($conn);
?>
LOB-Prefetch erfolgreich deaktiviert.

// Wichtig · Fallstricke

Reihenfolge der Aufrufe: oci_set_prefetch_lob muss zwingend nach oci_parse und vor oci_execute aufgerufen werden. Ein Aufruf nach der Ausführung hat keine Wirkung.

Speicherverbrauch: Bei aktiviertem Zeilenprefetch (via oci_set_prefetch) multipliziert sich der Speicherbedarf: Anzahl der vorab geladenen Zeilen × LOB-Prefetch-Größe × Anzahl LOB-Spalten. Große Werte können schnell zu erheblichem Speicherverbrauch führen.

Verfügbarkeit: Diese Funktion steht ab PHP 8.2.0 zusammen mit OCI8 3.2 und Oracle Client 12.2 (oder neuer) zur Verfügung. Sie hat keine Wirkung bei älteren Oracle-Client-Bibliotheken.

Alternative für ältere PHP-Versionen: In PHP-Versionen vor 8.2 kann das LOB-Prefetching über die INI-Direktive oci8.prefetch_lob_size global konfiguriert werden.