Запрос Oracle использует больше временного пространства, чем обычно - PullRequest
4 голосов
/ 17 февраля 2011

Один из наших клиентов сообщает нам, что процесс не может быть завершен, потому что ему не хватает временного пространства (20 ГБ).Процесс является частью стандартного программного обеспечения, и нам обычно требуется не более 300 МБ временного пространства.

Мы начали следить за временным пространством (примечание Metalink: 364417.1) и нашли ошибочный запрос.Мы также запустили процесс с трассировкой sql, как в нашей базе данных клиентов, так и в нашей базе данных.(Оба Oracle 10.2.0.5, точно такая же версия нашего приложения, точно такие же данные)

Вот разница:

Трассировка из нашей базы данных:

SELECT OBC1.BCT_ID BCT_ID 
FROM
 NGG_OBJECTBASISCOMPONENT OBC1 ,NGG_OBJECTBASISCOMPONENT OBC2 ,NGG_OBJECT 
  OBJ1 ,NGG_OBJECT OBJ2 ,NGG_LAAGBASISCOMPONENT LBC1 ,NGG_LAAGBASISCOMPONENT 
  LBC2 WHERE OBC1.BCT_ID = OBC2.BCT_ID AND OBC1.OBJ_ID = OBJ1.ID AND 
  OBC2.OBJ_ID = OBJ2.ID AND OBJ1.ODE_ID IS NULL AND OBJ2.ODE_ID IS NULL AND 
  OBC1.LBC_ID = LBC1.ID AND OBC2.LBC_ID = LBC2.ID AND OBJ1.ID > OBJ2.ID AND 
  OBJ1.TRE_ID_V IS NULL AND OBJ2.TRE_ID_V IS NULL AND LBC1.LDE_ID = :B2 AND 
  LBC1.LDE_ID = LBC2.LDE_ID AND OBJ1.TRE_ID_O = :B1 AND LBC1.FOUT = 0


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse       24      0.01       0.00          0          0          0           0
Execute     26      0.04       0.04          0          0          0           0
Fetch       26      0.15       0.14          0      11932          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       76      0.21       0.18          0      11932          0           0

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 63     (recursive depth: 2)

Rows     Row Source Operation
-------  ---------------------------------------------------
      0  NESTED LOOPS  (cr=3 pr=0 pw=0 time=181 us)
      0   NESTED LOOPS  (cr=3 pr=0 pw=0 time=155 us)
      0    NESTED LOOPS  (cr=3 pr=0 pw=0 time=133 us)
      0     NESTED LOOPS  (cr=3 pr=0 pw=0 time=110 us)
      0      NESTED LOOPS  (cr=3 pr=0 pw=0 time=91 us)
      0       TABLE ACCESS BY INDEX ROWID NGG_OBJECT (cr=3 pr=0 pw=0 time=65 us)
      0        INDEX RANGE SCAN NGG_OBJ_TRE_FK_O_I (cr=3 pr=0 pw=0 time=40 us)(object id 49579)
      0       TABLE ACCESS BY INDEX ROWID NGG_OBJECTBASISCOMPONENT (cr=0 pr=0 pw=0 time=0 us)
      0        INDEX RANGE SCAN NGG_OBC_OBJ_FK_I (cr=0 pr=0 pw=0 time=0 us)(object id 49586)
      0      TABLE ACCESS BY INDEX ROWID NGG_OBJECTBASISCOMPONENT (cr=0 pr=0 pw=0 time=0 us)
      0       INDEX RANGE SCAN NGG_OBC_BCT_FK_I (cr=0 pr=0 pw=0 time=0 us)(object id 49585)
      0     TABLE ACCESS BY INDEX ROWID NGG_OBJECT (cr=0 pr=0 pw=0 time=0 us)
      0      INDEX UNIQUE SCAN NGG_OBJ_PK (cr=0 pr=0 pw=0 time=0 us)(object id 49596)
      0    TABLE ACCESS BY INDEX ROWID NGG_LAAGBASISCOMPONENT (cr=0 pr=0 pw=0 time=0 us)
      0     INDEX UNIQUE SCAN NGG_LBC_PK (cr=0 pr=0 pw=0 time=0 us)(object id 49591)
      0   TABLE ACCESS BY INDEX ROWID NGG_LAAGBASISCOMPONENT (cr=0 pr=0 pw=0 time=0 us)
      0    INDEX UNIQUE SCAN NGG_LBC_PK (cr=0 pr=0 pw=0 time=0 us)(object id 49591)

********************************************************************************

Трассировка из нашей базы данных клиентов такая же, за исключением количества извлеченных строк:

********************************************************************************

SELECT OBC1.BCT_ID BCT_ID 
FROM
 NGG_OBJECTBASISCOMPONENT OBC1 , NGG_OBJECTBASISCOMPONENT OBC2 , NGG_OBJECT 
  OBJ1 , NGG_OBJECT OBJ2 , NGG_LAAGBASISCOMPONENT LBC1 , 
  NGG_LAAGBASISCOMPONENT LBC2   WHERE OBC1.BCT_ID =  OBC2.BCT_ID  AND 
  OBC1.OBJ_ID =  OBJ1.ID  AND OBC2.OBJ_ID =  OBJ2.ID  AND OBJ1.ODE_ID IS NULL 
    AND OBJ2.ODE_ID IS NULL   AND OBC1.LBC_ID =  LBC1.ID  AND OBC2.LBC_ID =  
  LBC2.ID  AND OBJ1.ID >  OBJ2.ID  AND OBJ1.TRE_ID_V IS NULL   AND 
  OBJ2.TRE_ID_V IS NULL   AND LBC1.LDE_ID =  :b1  AND LBC1.LDE_ID =  
  LBC2.LDE_ID  AND OBJ1.TRE_ID_O =  :b2  AND LBC1.FOUT =  0   


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse       24      0.00       0.00          0          0          0           0
Execute     26      0.04       0.04          0          0          0           0
Fetch       26   2414.90    2521.04     258210  624771631          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       76   2414.95    2521.09     258210  624771631          0           0

Misses in library cache during parse: 2
Misses in library cache during execute: 2
Optimizer mode: ALL_ROWS
Parsing user id: 64     (recursive depth: 2)

Rows     Row Source Operation
-------  ---------------------------------------------------
      0  NESTED LOOPS  (cr=3 pr=0 pw=0 time=51 us)
      0   NESTED LOOPS  (cr=3 pr=0 pw=0 time=47 us)
      0    NESTED LOOPS  (cr=3 pr=0 pw=0 time=43 us)
      0     NESTED LOOPS  (cr=3 pr=0 pw=0 time=42 us)
      0      NESTED LOOPS  (cr=3 pr=0 pw=0 time=38 us)
      0       TABLE ACCESS BY INDEX ROWID NGG_OBJECT (cr=3 pr=0 pw=0 time=35 us)
      0        INDEX RANGE SCAN NGG_OBJ_TRE_FK_O_I (cr=3 pr=0 pw=0 time=31 us)(object id 49947)
      0       TABLE ACCESS BY INDEX ROWID NGG_OBJECTBASISCOMPONENT (cr=0 pr=0 pw=0 time=0 us)
      0        INDEX RANGE SCAN NGG_OBC_OBJ_FK_I (cr=0 pr=0 pw=0 time=0 us)(object id 49954)
      0      TABLE ACCESS BY INDEX ROWID NGG_OBJECTBASISCOMPONENT (cr=0 pr=0 pw=0 time=0 us)
      0       INDEX RANGE SCAN NGG_OBC_BCT_FK_I (cr=0 pr=0 pw=0 time=0 us)(object id 49953)
      0     TABLE ACCESS BY INDEX ROWID NGG_OBJECT (cr=0 pr=0 pw=0 time=0 us)
      0      INDEX UNIQUE SCAN NGG_OBJ_PK (cr=0 pr=0 pw=0 time=0 us)(object id 49964)
      0    TABLE ACCESS BY INDEX ROWID NGG_LAAGBASISCOMPONENT (cr=0 pr=0 pw=0 time=0 us)
      0     INDEX UNIQUE SCAN NGG_LBC_PK (cr=0 pr=0 pw=0 time=0 us)(object id 49959)
      0   TABLE ACCESS BY INDEX ROWID NGG_LAAGBASISCOMPONENT (cr=0 pr=0 pw=0 time=0 us)
      0    INDEX UNIQUE SCAN NGG_LBC_PK (cr=0 pr=0 pw=0 time=0 us)(object id 49959)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  direct path write temp                      17522        0.00          0.06
  direct path read temp                       17214        0.00          0.07
  latch: cache buffers chains                     1        0.00          0.00

Производит ли этот запрос декартово произведение?Почему только на этом конкретном экземпляре базы данных?

Что еще я могу сделать, чтобы выяснить, что происходит?

Ответы [ 2 ]

1 голос
/ 17 февраля 2011

Интересно, является ли этот план тем, что генерирует опция EXPLAIN в TKPROF, а не фактическим планом выполнения во время работы.Попробуйте захватить запрос по мере его выполнения (или правильно, если он не будет выполнен) с помощью запроса данных AWR или v $ sql / v $ sql_plan - подробнее см. этот поток на asktom .

(я говорюэто потому, что в представленном плане нет ничего, что могло бы использовать временное пространство, при условии, что ни одна из них не является глобальной временной таблицей)

0 голосов
/ 18 февраля 2011

Во-первых, глядя на эту строку "Fetch 26 2414.90 2521.04", вы можете видеть, что почти все время затрачивается на процессор.Это подтверждается перечисленными ожиданиями, которые составляют всего 0,06 и 0,07.Совершенно несущественно.

Так что этот план запроса НИЧЕГО не имеет отношения к временному режиму, и все это связано с ЦП.В общих чертах, план запроса выглядит следующим образом:

SELECT OBC1.BCT_ID BCT_ID 
FROM  NGG_OBJECT OBJ1 
 join NGG_OBJECTBASISCOMPONENT OBC1 on (OBC1.OBJ_ID =  OBJ1.ID) 
 join NGG_OBJECTBASISCOMPONENT OBC2 on (OBC1.BCT_ID =  OBC2.BCT_ID ) 
 join NGG_OBJECT OBJ2 on (OBC2.OBJ_ID =  OBJ2.ID  ) 
 join NGG_LAAGBASISCOMPONENT LBC1 on (OBC1.LBC_ID = LBC1.ID) 
 join NGG_LAAGBASISCOMPONENT LBC2 on (OBC2.LBC_ID = LBC2.ID)
WHERE OBJ1.TRE_ID_O =  :b2
  AND LBC1.LDE_ID =  LBC2.LDE_ID  
  AND OBJ1.ID >  OBJ2.ID  
  AND OBJ1.ODE_ID IS NULL 
  AND OBJ2.ODE_ID IS NULL   
  AND OBJ1.TRE_ID_V IS NULL   
  AND OBJ2.TRE_ID_V IS NULL   
  AND LBC1.LDE_ID =  :b1  
  AND LBC1.FOUT =  0   

Учитывая отсутствие ожидания чтения с диска, я подозреваю, что у вас есть все индексы в памяти и, возможно, таблицы.Я подозреваю, что многие строки соответствуют этому первому фильтру TRE_ID_O и что каждое совпадение затем попадает в таблицу NGG_OBJECT и, возможно, исключается любым из условий OBJ1.ODE_ID IS NULL / OBJ1.TRE_ID_V IS NULL (или обоих).

Что такое тома таблицы?Есть ли порядка 10 миллионов строк, соответствующих значению TRE_ID_O.

Я бы не удивился, если бы существовал альтернативный план с использованием хеш-соединений (который использовал бы temp)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...