Схема I и Oracle (11 Enterprise) с таблицей
CREATE TABLE USER.WSP_BUNDLE (
NODE_ID RAW(16) NOT NULL,
BUNDLE_DATA BLOB NOT NULL
);
CREATE UNIQUE INDEX USER.WSP_BUNDLE_IDX ON USER.WSP_BUNDLE(NODE_ID);
и сторонняя библиотека (Java 6, JDBC - последний драйвер jdbc), которая управляет им.
Профайлер Oracle (tkprof) показывает, что примерно 50% всего времени, когда библиотека выполняет такой оператор:
update WSP_BUNDLE set BUNDLE_DATA = :1 where NODE_ID = :2
Данные ТКПроф
Plan Hash: 4085453680
update WSP_BUNDLE set BUNDLE_DATA = :1 where NODE_ID = :2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 264 0.00 0.00 0 0 0 0
Execute 400 30.59 382.88 141451 1623163 3233827 400
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 664 30.59 382.88 141451 1623163 3233827 400
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 87
Rows Row Source Operation
------- ---------------------------------------------------
0 UPDATE WSP_BUNDLE (cr=8753 pr=707 pw=706 time=0 us)
1 INDEX UNIQUE SCAN WSP_BUNDLE_IDX (cr=3 pr=0 pw=0 time=0 us cost=2 size=104 card=1)(object id 75730)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 141251 5.53 328.04
direct path write 402 0.09 0.43
SQL*Net more data from client 142158 1.04 11.89
direct path read 200 0.03 0.07
Disk file operations I/O 1 0.00 0.00
SQL*Net message to client 400 0.00 0.00
SQL*Net message from client 400 0.29 0.50
log file switch (private strand flush incomplete)
5 0.05 0.23
asynch descriptor resize 139723 7.46 8.57
buffer busy waits 2 0.00 0.00
log file switch (checkpoint incomplete) 3 0.18 0.27
log file sync 2 0.00 0.00
Может ли кто-нибудь объяснить / намекнуть мне, что происходит? Почему обновление такое медленное?
Таблица WSP_BUNDLE содержит около 200 + k строк. В то же время у меня есть другие таблицы в той же схеме с большими двоичными объектами (CLOB, чтобы быть более конкретными), которые содержат 600 + k строк, где аналогичные обновления работают правильно.
В Oracle LOB (включая BLOB) хранится как:
Следовательно, если ваши большие объекты больше 4 КБ, они будут относительно медленными, и это может быть просто ваш случай. Я бы рассмотрел размеры.
Я бы изучил USER_LOBS (или DBA_LOBS), чтобы увидеть, как «хорошие» и «медленные» столбцы LOB различаются по своим определениям.
Об этом говорится в заметке Metalink с идентификатором 66431.1, которая может вас заинтересовать, если у вас есть к ней доступ.
ОБНОВИТЬ: Очарованный, казалось бы, необъяснимым диким объемом "последовательного чтения файла db", я немного поискал и обнаружил, что странные вещи могут происходить с индексом lob после массовых DELETE. Просто предположение, но очень похоже на ваш случай. Если это так, я бы полностью перестроить столбец lob. (Перемещение столбца lob также может перестроить индекс lob - я не уверен).