$title =

Direct Path Read – Possíveis causas e soluções

;

$conteúdo = [

Introdução

Fala pessoal! No post de hoje eu planejo explicar um pouco do wait event Direct Path Read, o que é, como consultar e quais as possíveis soluções para ele. Ao longo do post vocês vão ver que apesar de ser um Wait Event, ele não necessariamente é um problema para o seu banco de dados, em muitos casos ele serve até para evitar poluição da Buffer Cache.

Espero que gostem do post, e bora lá analisar um pouco desse wait.

O que é o Direct Path Read?

Para iniciar o post, vou comentar um pouco sobre o que é o Direct Path Read. Basicamente ele é um Wait Event de I/O físico em que uma sessão do Oracle está esperando uma leitura direta de disco terminar.

Sua principal característica é que os blocos são lidos diretamente dos datafiles para a memória privada do processo (process-private memory), normalmente localizada na PGA, sem utilizar o Buffer Cache da SGA como destino da leitura.

Em leituras comuns (db file sequencial read ou db file scattered por exemplo) o fluxo seria o seguinte:

Disco/datafile -->>>>>>>> Buffer Cache -->>>>>>>> Sessão utiliza os blocos

Já no Direct Path Read, o fluxo seria:

Disco/datafile -->>>>>>>> PGA/process-private memory -->>>>>>>> Sessão utiliza os blocos

Por que o Oracle realiza o Direct Path Read?

Ele faz isso porque em alguns casos não vale a pena poluir a Buffer Cache com blocos que provavelmente serão lidos uma única vez, essa poluição ocorreria pois o Buffer Cache possui um algoritmo baseado em LRU (least-recently-used) então mesmo um FULL TABLE SCAN ocorrendo uma única vez, já poderia ser o suficiente para poluir a Buffer Cache (mesmo que não completamente graças ao mecanismo Touch Count)

Situações onde o Direct Path Read costuma aparecer:

  • Full Table Scan em objetos grandes
  • Parallel Query
  • CREATE TABLE AS SELECT

Por isso, é possível dizer que o Direct Path Read não é necessariamente ruim. Ele pode ajudar muito para leituras grandes. Ele poderia ser um problema em situações onde:

  • I/O está lento
  • Plano de execução está ruim
  • SQL está lendo blocos demais
  • Wait Time está muito alto

Uma query que deveria retornar apenas 10 linhas mas está fazendo um full table scan por exemplo, pode indicar um plano de execução inadequado. Nesse cenário, o objetivo não é se preocupar com o Direct Path Read, mas sim corrigir a causa que levou o Oracle a realizar um Full Table Scan desnecessário.

Formas de reduzir o Direct Path Read

A diminuição desse wait event vai depender muito da causa raiz.

No caso de ser SQL ruim:

  • Criar índices adequados
  • Atualizar estatísticas
  • Reescrever query
  • Evitar funções em colunas filtradas
  • Melhorar seletividade dos predicados

No caso de ser leituras massivas em paralelo:

  • Verificar o nível adequado de PARALLEL (caso ele realmente seja necessário)

No caso do plano de execução estar errado:

  • Avaliar a coleta de estatísticas
  • Avaliar se há histogramas adequados para as colunas envolvidas
  • Verificar se a configuração dos índices realmente está refinada o suficiente para essa consulta.

Formas de identificar o Direct Path Read:

Através da view V$/GV$session por exemplo é possível identificar esse wait

SQL> SELECT
sid,
serial#,
sql_id,
event,
state,
seconds_in_wait
FROM v$session
WHERE event='direct path read';
SID SERIAL# SQL_ID EVENT STATE SECONDS_IN_WAIT
---------- ---------- ------------- -------------------- --------------------- ----------------
184 58712 4g7w5v2s9r4nh direct path read WAITING 0
251 19103 8b3h2jv9m5nka direct path read WAITING 0
337 44290 a4nk7x5j1h2qp direct path read WAITING 1
412 30874 d2v8t6p4m1zwr direct path read WAITING 0

Fora isso, o AWR ou Statspack também possuem informações muito úteis para esse troubleshoot

Conclusão

O wait event de Direct Path read não necessariamente me parece algo ruim de estar presente nos ambientes de banco de dados Oracle, em alguns casos ele serve até mesmo como um mecanismo de proteção para a SGA manter os blocos mais relevantes possíveis em memória. Mas em casos onde ele é muito recorrente e o Wait Time dele estiver muito alto, um SQL Tuning pode ser o caminho ideal para resolver isso.

];

$namorado(a) =

;

$category =

;

$author =

;

$next =

;