No Oracle Database, os índices são estruturas de dados que melhoram o desempenho das consultas ao permitir que o sistema localize rapidamente as linhas relevantes em uma tabela. Além disso, os operadores de plano de acesso determinam como o Oracle acessará os dados para executar uma consulta. Aqui estão alguns tipos de índices e os principais operadores de plano de acesso no Oracle:
Tipos de Índices no Oracle:
- Índice B-Tree: Este é o tipo de índice mais comum no Oracle. Ele é usado para consultas de igualdade e intervalos.
- Índice Bitmap: Índices bitmap são eficazes para colunas com um número limitado de valores distintos (baixa cardinalidade). Eles são frequentemente usados para colunas booleanas ou categorias discretas.
- Índice de Árvore de Extensão (Index-Organized Table - IOT): Este tipo de índice é usado em conjunto com as tabelas organizadas por índice. Ele armazena todos os dados na estrutura do índice, em vez de uma tabela separada.
- Índice de Cluster: Um índice de cluster é usado quando as linhas da tabela estão fisicamente agrupadas com base em uma coluna comum. O índice de cluster ajuda a localizar eficientemente o grupo de linhas relacionadas.
- Índice Funcional: Este tipo de índice é criado com base em uma expressão ou função em uma ou mais colunas da tabela. É útil para consultas que envolvem operações de função em colunas.
Principais Operadores de Plano de Acesso no Oracle:
- Full Table Scan: Este operador lê todas as linhas de uma tabela, geralmente quando não há índices adequados ou quando a porcentagem de linhas correspondentes é alta.
- Index Scan (Range Scan): O Oracle usa um índice B-tree para localizar intervalos de valores específicos. É útil para consultas que envolvem operações de intervalo.
- Index Unique Scan: Esse operador é usado quando o Oracle pode usar um índice para encontrar uma única linha com base em uma chave exclusiva.
- Index Fast Full Scan: É semelhante ao Full Table Scan, mas usa um índice B-tree para recuperar todas as linhas de uma tabela de forma mais eficiente.
- Hash Join: Este operador é usado para mesclar duas tabelas usando uma função de hash. É eficaz para consultas de junção quando há um índice hash disponível.
- Nested Loop Join: É um operador usado em junções, onde o Oracle usa um loop aninhado para comparar cada linha de uma tabela com cada linha de outra tabela.
- Sort Merge Join: Este operador é usado quando o Oracle precisa ordenar as tabelas de junção antes de realizar a junção.
- Table Access by Rowid: Esse operador permite ao Oracle acessar uma linha específica de uma tabela com base em seu ROWID. A escolha do operador de plano de acesso depende da estrutura da consulta, da disponibilidade de índices e das estatísticas de tabela. O Oracle utiliza otimização de consulta para escolher automaticamente o plano de acesso mais eficiente com base nas informações disponíveis.
Observe que a eficiência das consultas pode depender de fatores como índices, estatísticas de tabela, tamanho dos dados e otimização do sistema. Portanto, os exemplos acima são apenas para ilustrar os operadores de plano de acesso e não refletem necessariamente as melhores práticas de otimização de consultas em todos os cenários.
Aqui estão exemplos de como criar tabelas no Oracle com diferentes tipos de índices:
- Índice B-Tree:
O exemplo acima cria uma tabela "employees" com um índice B-Tree na coluna "last_name" para melhorar o desempenho das consultas de pesquisa por sobrenome.
CREATE TABLE employees ( employee_id NUMBER PRIMARY KEY, first_name VARCHAR2(50), last_name VARCHAR2(50), hire_date DATE ); CREATE INDEX idx_employee_last_name ON employees(last_name);
- Índice Bitmap:
Neste exemplo, uma tabela "products" é criada com um índice bitmap na coluna "category_id". Este tipo de índice é adequado quando a coluna "category_id" tem baixa cardinalidade.
CREATE TABLE products ( product_id NUMBER PRIMARY KEY, product_name VARCHAR2(100), category_id NUMBER ); CREATE BITMAP INDEX idx_product_category ON products(category_id);
- Índice de Árvore de Extensão (Index-Organized Table - IOT):
Aqui, uma tabela "orders" é criada como uma tabela organizada por índice (IOT), onde os dados são armazenados diretamente na estrutura do índice. Em seguida, é criado um índice B-Tree na coluna "order_date".
CREATE TABLE orders ( order_id NUMBER PRIMARY KEY, order_date DATE, customer_name VARCHAR2(100) ) ORGANIZATION INDEX; CREATE INDEX idx_order_date ON orders(order_date);
- Índice de Cluster:
Neste exemplo, uma tabela "departments" é criada como uma tabela de cluster com base na coluna "department_id". Em seguida, é criado um índice B-Tree na coluna "department_name".
CREATE CLUSTER departments_cluster (department_id NUMBER) SIZE 1024; CREATE TABLE departments ( department_id NUMBER, department_name VARCHAR2(100), location VARCHAR2(100) ) CLUSTER departments_cluster (department_id); CREATE INDEX idx_department_name ON departments(department_name);
- Índice Funcional:
Aqui, é criada uma tabela "products" com um índice B-Tree na expressão "UPPER(product_name)". Este é um exemplo de índice funcional que melhora o desempenho das consultas de pesquisa sem diferenciar maiúsculas de minúsculas no nome do produto. Lembre-se de que a escolha de criar ou não um índice e o tipo de índice dependem dos requisitos específicos de sua aplicação e das consultas que você pretende executar com mais frequência. Além disso, é importante considerar o custo de manutenção de índices à medida que os dados são inseridos, atualizados ou excluídos.
CREATE TABLE products ( product_id NUMBER PRIMARY KEY, product_name VARCHAR2(100), price NUMBER ); CREATE INDEX idx_upper_product_name ON products(UPPER(product_name));
Certamente, vou fornecer exemplos de consultas SQL para cada um dos operadores de plano de acesso no Oracle, junto com comentários explicativos.
-
Full Table Scan:
Um Full Table Scan ocorre quando o Oracle precisa ler todas as linhas de uma tabela. Isso geralmente acontece quando não há índices adequados ou quando a porcentagem de linhas correspondentes é alta.
SELECT * FROM employees;
-
Index Scan (Range Scan): Um Index Scan é usado para recuperar intervalos de valores de uma coluna indexada.
SELECT * FROM products WHERE price BETWEEN 50 AND 100;
-
Index Unique Scan: Um Index Unique Scan é usado quando o Oracle pode usar um índice para encontrar uma única linha com base em uma chave exclusiva.
SELECT * FROM employees WHERE employee_id = 101;
-
Index Fast Full Scan: Um Index Fast Full Scan é semelhante a um Full Table Scan, mas usa um índice B-tree para recuperar todas as linhas de uma tabela de forma mais eficiente.
SELECT * FROM orders WHERE order_date >= TO_DATE('2023-01-01', 'YYYY-MM-DD');
-
Hash Join: Um Hash Join é usado para mesclar duas tabelas usando uma função de hash.
SELECT * FROM employees e JOIN departments d ON e.department_id = d.department_id;
-
Nested Loop Join: Um Nested Loop Join é usado em junções, onde o Oracle usa um loop aninhado para comparar cada linha de uma tabela com cada linha de outra tabela.
SELECT * FROM employees e WHERE e.department_id = (SELECT department_id FROM departments WHERE department_name = 'Sales');
-
Sort Merge Join: Um Sort Merge Join é usado quando o Oracle precisa ordenar as tabelas de junção antes de realizar a junção.
SELECT * FROM employees e JOIN salaries s ON e.employee_id = s.employee_id ORDER BY e.employee_id;
-
Table Access by Rowid: O operador Table Access by Rowid permite ao Oracle acessar uma linha específica de uma tabela com base em seu ROWID. O ROWID é uma identificação única para cada linha na tabela.
SELECT * FROM employees WHERE ROWID = 'AAARiLAABAAAH92AAA';