Seguindo o Highload ++ Siberia 2019 - 8 Oracle Tasks

Oi

De 24 a 25 de junho, a conferência Highload ++ Siberia 2019 foi realizada em Novosibirsk. Nossos funcionários também estavam no relatório "Oracle Container Bases (CDB / PDB) e seu uso prático para desenvolvimento de software", publicaremos uma versão em texto um pouco mais tarde. Foi legal, obrigado olegbunin pela organização, assim como a todos que vieram.


Nesta postagem, gostaríamos de compartilhar com você as tarefas que estavam em nosso estande para que você possa testar seus conhecimentos no Oracle. Sob o corte - 8 tarefas, responda às opções e explicações.

Qual é o valor máximo da sequência que veremos como resultado do script a seguir?


create sequence s start with 1; select s.currval, s.nextval, s.currval, s.nextval, s.currval from dual connect by level <= 5; 

  • 1
  • 5
  • 10
  • 25
  • Não, haverá um erro

A resposta
De acordo com a documentação da Oracle (citada em 8.1.6):
Dentro de uma única instrução SQL, o Oracle incrementará a sequência apenas uma vez por linha. Se uma instrução contiver mais de uma referência ao NEXTVAL para uma sequência, o Oracle incrementará a sequência uma vez e retornará o mesmo valor para todas as ocorrências do NEXTVAL. Se uma instrução contiver referências a CURRVAL e NEXTVAL, o Oracle incrementará a sequência e retornará o mesmo valor para CURRVAL e NEXTVAL, independentemente de sua ordem na instrução.

Assim, o valor máximo corresponderá ao número de linhas, ou seja, 5 .

Quantas linhas estarão na tabela como resultado do seguinte script?


 create table t(i integer check (i < 5)); create procedure p(p_from integer, p_to integer) as begin for i in p_from .. p_to loop insert into t values (i); end loop; end; / exec p(1, 3); exec p(4, 6); exec p(7, 9); 

  • 0 0
  • 3
  • 4
  • 5
  • 6
  • 9

A resposta
De acordo com a documentação da Oracle (citada em 11.2):

Antes de executar qualquer instrução SQL, o Oracle marca um ponto de salvamento implícito (não disponível para você). Em seguida, se a instrução falhar, o Oracle reverte automaticamente e retorna o código de erro aplicável para SQLCODE no SQLCA. Por exemplo, se uma instrução INSERT causar um erro ao tentar inserir um valor duplicado em um índice exclusivo, a instrução será revertida.

Uma chamada do cliente também é considerada e processada como uma única declaração. Portanto, a primeira chamada para a HP é concluída com êxito, inserindo três registros; a segunda chamada para a HP termina com um erro e reverte o quarto registro, que eu consegui inserir; a terceira chamada falha e três entradas aparecem na tabela .

Quantas linhas estarão na tabela como resultado do seguinte script?


 create table t(i integer, constraint i_ch check (i < 3)); begin insert into t values (1); insert into t values (null); insert into t values (2); insert into t values (null); insert into t values (3); insert into t values (null); insert into t values (4); insert into t values (null); insert into t values (5); exception when others then dbms_output.put_line('Oops!'); end; / 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

A resposta
De acordo com a documentação da Oracle (citada em 11.2):

Uma restrição de verificação permite especificar uma condição que cada linha da tabela deve atender. Para satisfazer a restrição, cada linha da tabela deve tornar a condição TRUE ou desconhecida (devido a um nulo). Quando o Oracle avalia uma condição de restrição de verificação para uma linha específica, qualquer nome de coluna na condição se refere aos valores da coluna nessa linha.

Assim, o valor nulo passará no teste e o bloco anônimo será executado com êxito até a tentativa de inserir o valor 3. Depois disso, o bloco de processamento de erros lançará a exceção, a reversão não ocorrerá e a tabela terá quatro linhas com os valores 1, nulo, 2 e nulo novamente.

Quais pares de valores ocuparão a mesma quantidade de espaço no bloco?


 create table t ( a char(1 char), b char(10 char), c char(100 char), i number(4), j number(14), k number(24), x varchar2(1 char), y varchar2(10 char), z varchar2(100 char)); insert into t (a, b, i, j, x, y) values ('Y', '', 10, 10, '', ''); 

  • A e X
  • B e Y
  • C e K
  • C e Z
  • K e Z
  • Eu e J
  • J e X
  • Todos listados

A resposta
Aqui estão trechos da documentação (12.1.0.2) para armazenar vários tipos de dados no Oracle.

Tipo de dados Char
O tipo de dados CHAR especifica uma cadeia de caracteres de comprimento fixo no conjunto de caracteres do banco de dados. Você especifica o conjunto de caracteres do banco de dados ao criar seu banco de dados. O Oracle garante que todos os valores armazenados em uma coluna CHAR tenham o comprimento especificado por tamanho na semântica de comprimento selecionada. Se você inserir um valor menor que o comprimento da coluna, o Oracle colocará em branco o valor no comprimento da coluna.

Tipo de Dados VARCHAR2
O tipo de dados VARCHAR2 especifica uma cadeia de caracteres de comprimento variável no conjunto de caracteres do banco de dados. Você especifica o conjunto de caracteres do banco de dados ao criar seu banco de dados. O Oracle armazena um valor de caractere em uma coluna VARCHAR2 exatamente como você o especifica, sem preenchimento em branco, desde que o valor não exceda o comprimento da coluna.

NUMBER Tipo de Dados
O tipo de dados NUMBER armazena zero e números fixos positivos e negativos com valores absolutos de 1,0 x 10-130 a mas sem incluir 1,0 x 10126. Se você especificar uma expressão aritmética cujo valor possua um valor absoluto maior ou igual a 1,0 x 10126, o Oracle retorna um erro. Cada valor NUMBER requer de 1 a 22 bytes. Levando isso em consideração, o tamanho da coluna em bytes para um determinado valor numérico de dados NUMBER (p), em que p é a precisão de um determinado valor, pode ser calculado usando a seguinte fórmula: ROUND ((length (p) + s) / 2)) + 1 onde s é igual a zero se o número for positivo es s é igual a 1 se o número for negativo.

Além disso, extraímos um trecho da documentação sobre o armazenamento de valores nulos.

Um nulo é a ausência de um valor em uma coluna. Nulos indicam dados ausentes, desconhecidos ou inaplicáveis. Os nulos são armazenados no banco de dados se eles caírem entre colunas com valores de dados. Nesses casos, eles exigem 1 byte para armazenar o comprimento da coluna (zero). O nulo à direita em uma linha não requer armazenamento, porque um novo cabeçalho de linha sinaliza que as colunas restantes na linha anterior são nulas. Por exemplo, se as últimas três colunas de uma tabela forem nulas, nenhum dado será armazenado para essas colunas.

Com base nesses dados, criamos raciocínio. Acreditamos que o banco de dados usa a codificação AL32UTF8. Nessa codificação, as letras russas ocuparão 2 bytes.

1) A e X, o valor do campo a 'Y' é 1 byte, o valor do campo x 'D' é 2 bytes
2) B e Y, 'Vasya' no valor b será complementado com espaços de até 10 caracteres e ocupará 14 bytes, 'Vasya' em d - terá 8 bytes.
3) C e K. Ambos os campos são NULL; depois deles, existem campos significativos; portanto, eles ocupam 1 byte.
4) C e Z. Os dois campos são NULL, mas o campo Z é o último da tabela, portanto, não ocupa espaço (0 bytes). O campo C ocupa 1 byte.
5) K e Z. Semelhante ao caso anterior. O valor no campo K é de 1 byte, em Z - 0.
6) I e J. De acordo com a documentação, ambos os valores terão 2 bytes cada. Consideramos o comprimento de acordo com a fórmula obtida na documentação: round ((1 + 0) / 2) +1 = 1 + 1 = 2.
7) J e X. O valor no campo J terá 2 bytes, o valor no campo X terá 2 bytes.

No total, as opções corretas são: C e K, I e J, J e X.


Qual será o fator de cluster do índice T_I aproximadamente?


 create table t (i integer); insert into t select rownum from dual connect by level <= 10000; create index t_i on t(i); 

  • Cerca de dezenas
  • Cerca de centenas
  • Da ordem dos milhares
  • Da ordem de dezenas de milhares

A resposta
De acordo com a documentação do Oracle (citada em 12.1):

Para um índice de árvore B, o fator de cluster de índice mede o agrupamento físico de linhas em relação a um valor de índice.

O fator de cluster de índice ajuda o otimizador a decidir se uma varredura de índice ou varredura de tabela completa é mais eficiente para determinadas consultas). Um baixo fator de cluster indica uma verificação eficiente do índice.

Um fator de cluster próximo ao número de blocos em uma tabela indica que as linhas estão ordenadas fisicamente nos blocos da tabela pela chave de índice. Se o banco de dados executar uma varredura completa da tabela, o banco de dados tende a recuperar as linhas à medida que são armazenadas no disco, classificadas pela chave de índice. Um fator de cluster próximo ao número de linhas indica que as linhas estão espalhadas aleatoriamente pelos blocos do banco de dados em relação à chave de índice. Se o banco de dados executar uma verificação completa da tabela, o banco de dados não recuperará linhas em nenhuma ordem classificada por essa chave de índice.

Nesse caso, os dados são classificados de maneira ideal, portanto, o fator de agrupamento será igual ou próximo ao número de blocos ocupados na tabela. Para um tamanho de bloco padrão de 8 kilobytes, você pode esperar que cerca de mil valores de número restrito caibam em um bloco, portanto, o número de blocos e, como resultado, o fator de agrupamento será da ordem de dezenas .

Em que valores de N, o script a seguir será executado com êxito em um banco de dados regular com configurações padrão?


 create table t ( a varchar2(N char), b varchar2(N char), c varchar2(N char), d varchar2(N char)); create index t_i on t (a, b, c, d); 

  • 100
  • 200
  • 400
  • 800
  • 1600
  • 3200
  • 6400

A resposta
De acordo com a documentação da Oracle (citada em 11.2):

Limites de banco de dados lógicos

ItemTipo de limiteValor limite
ÍndicesTamanho total da coluna indexada75% do tamanho do bloco do banco de dados menos alguma sobrecarga

Portanto, o tamanho total das colunas indexadas não deve exceder 6 KB. Depende ainda da base de codificação selecionada. Para a codificação AL32UTF8, um caractere pode ocupar no máximo 4 bytes; portanto, no pior cenário, 6 kilobytes caberão cerca de 1.500 caracteres. Portanto, a Oracle proibirá a criação de um índice em N = 400 (quando o comprimento da chave, na pior das hipóteses, for 1600 caracteres * 4 bytes + comprimento da linha), enquanto em N = 200 (ou menos) a criação do índice funcionará sem problemas.

A instrução INSERT com a dica APPEND foi projetada para carregar dados no modo direto. O que acontece se for aplicado à tabela na qual o gatilho trava?


  • Os dados serão carregados no modo direto, o gatilho funcionará como deveria
  • Os dados serão carregados no modo direto, mas o gatilho não será executado
  • Os dados serão carregados no modo convencional, o gatilho funcionará como deveria
  • Os dados serão carregados no modo convencional, mas o gatilho não será executado
  • Os dados não serão enviados, o erro será corrigido

A resposta
Em princípio, isso é mais uma questão de lógica. Para encontrar a resposta certa, sugiro o seguinte modelo de raciocínio:

  1. A inserção no modo direto é realizada pela formação direta de um bloco de dados, além do mecanismo SQL, que garante alta velocidade. Portanto, garantir a execução do gatilho é muito difícil, se possível, e não faz sentido, pois isso diminuirá drasticamente a inserção.
  2. A falha no acionamento levará ao fato de que, com os mesmos dados na tabela, o estado do banco de dados como um todo (de outras tabelas) dependerá de qual modo os dados são inseridos. Obviamente, isso destruirá a integridade dos dados e não poderá ser aplicado como uma solução na produção.
  3. A incapacidade de executar a operação solicitada, em geral, é tratada como um erro. Mas aqui deve ser lembrado que APPEND é uma dica, e a lógica geral das dicas é que elas são levadas em consideração se possível, se não, o operador é executado sem levar em conta a dica.

Portanto, a resposta esperada é que os dados sejam carregados no modo normal (SQL), o gatilho será acionado.

De acordo com a documentação da Oracle (citada em 8.04):

As violações das restrições farão com que a instrução seja executada em série, usando o caminho de inserção convencional, sem avisos ou mensagens de erro. Uma exceção é a restrição de instruções que acessam a mesma tabela mais de uma vez em uma transação, o que pode causar mensagens de erro.
Por exemplo, se gatilhos ou integridade referencial estiverem presentes na tabela, a dica APPEND será ignorada quando você tentar usar o INSERT de carregamento direto (serial ou paralelo), bem como a dica ou cláusula PARALLEL, se houver.

O que acontece ao executar o seguinte script?


 create table t(i integer not null primary key, j integer references t); create trigger t_a_i after insert on t for each row declare pragma autonomous_transaction; begin insert into t values (:new.i + 1, :new.i); commit; end; / insert into t values (1, null); 

  • Execução bem sucedida
  • Erro de sintaxe falhou
  • Erro de transação offline inválido
  • Erro relacionado a exceder o aninhamento máximo de chamadas
  • Erro de violação de chave estrangeira
  • Erro de bloqueio

A resposta
A tabela e o gatilho foram criados corretamente e esta operação não deve causar problemas. Também são permitidas transações autônomas no acionador, caso contrário, seria impossível, por exemplo, o log.

Após inserir a primeira linha, um acionador bem-sucedido levaria à inserção da segunda linha, em conexão com a qual o acionador funcionaria novamente, inseriria a terceira linha e assim por diante até que a instrução caia devido a exceder o aninhamento máximo de chamadas. No entanto, outro ponto sutil é acionado. No momento em que o gatilho é executado, a confirmação ainda não é executada para o primeiro registro inserido. Portanto, um gatilho que trabalha em uma transação autônoma tenta inserir uma linha na tabela que se refere por uma chave estrangeira a um registro que ainda não foi confirmado. Isso leva a uma espera (uma transação autônoma aguarda a confirmação principal para entender se é possível inserir dados) e, ao mesmo tempo, a transação principal aguarda a confirmação autônoma continuar trabalhando após o acionador. O conflito ocorre e, como resultado, uma transação autônoma é revertida pelo motivo associado aos bloqueios .

Source: https://habr.com/ru/post/pt459680/


All Articles