Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle 10g Small Blob oder Clob wird nicht inline gespeichert?

Das Verhalten von Oracle LOBs ist wie folgt.

Ein LOB wird inline gespeichert, wenn:

(
  The size is lower or equal than 3964
  AND
  ENABLE STORAGE IN ROW has been defined in the LOB storage clause
) OR (
  The value is NULL
)

Ein LOB wird außerhalb der Reihe gespeichert, wenn:

(
  The value is not NULL
) AND (
  Its size is higher than 3964
  OR
  DISABLE STORAGE IN ROW has been defined in the LOB storage clause
)

Dies ist nun nicht das einzige Problem, das die Leistung beeinträchtigen kann.

Wenn die LOBs schließlich nicht inline gespeichert werden, besteht das Standardverhalten von Oracle darin, sie nicht zwischenzuspeichern (nur Inline-LOBs werden im Puffercache mit den anderen Feldern der Zeile zwischengespeichert). Um Oracle anzuweisen, auch nicht eingebettete LOBs zwischenzuspeichern, sollte die CACHE-Option verwendet werden, wenn das LOB definiert ist.

Das Standardverhalten ist ENABLE STORAGE IN ROW und NOCACHE, was bedeutet, dass kleine LOBs eingebettet werden, große LOBs nicht (und nicht zwischengespeichert werden).

Schließlich gibt es auch ein Leistungsproblem auf der Ebene des Kommunikationsprotokolls. Typische Oracle-Clients führen zwei zusätzliche Roundtrips pro LOBs durch, um sie abzurufen:- einen, um die Größe des LOBs abzurufen und Speicher entsprechend zuzuweisen - einen, um die Daten selbst abzurufen (vorausgesetzt, das LOB ist klein)

Diese zusätzlichen Roundtrips werden auch dann durchgeführt, wenn eine Array-Schnittstelle zum Abrufen der Ergebnisse verwendet wird. Wenn Sie 1000 Zeilen abrufen und Ihr Array groß genug ist, zahlen Sie für 1 Roundtrip zum Abrufen der Zeilen und 2000 Roundtrips zum Abrufen des Inhalts der LOBs.

Bitte beachten Sie, dass dies nicht der Fall ist hängen davon ab, ob das LOB inline gespeichert wird oder nicht. Das sind völlig unterschiedliche Probleme.

Zur Optimierung auf Protokollebene hat Oracle ein neues OCI-Verb bereitgestellt, um mehrere LOBs in einem Roundtrip abzurufen (OCILobArrayRead). Ich weiß nicht, ob etwas Ähnliches mit JDBC existiert.

Eine andere Option besteht darin, das LOB auf der Clientseite so zu binden, als wäre es ein großes RAW/VARCHAR2. Dies funktioniert nur, wenn eine maximale Größe des LOB definiert werden kann (da die maximale Größe zur Bindezeit angegeben werden muss). Dieser Trick vermeidet die zusätzlichen Roundtrips:Die LOBs werden nur wie RAW oder VARCHAR2 verarbeitet. Wir verwenden es häufig in unseren LOB-intensiven Anwendungen.

Sobald die Anzahl der Roundtrips optimiert wurde, kann die Paketgröße (SDU) in der Netzkonfiguration angepasst werden, um sie besser an die Situation anzupassen (d. h. eine begrenzte Anzahl großer Roundtrips). Es neigt dazu, die Warteereignisse "SQL*Net more data to client" und "SQL*Net more data from client" zu reduzieren.