iec banco de dados i aula 17 – otimização modelo relacional turmas: sistemas de informação...
TRANSCRIPT
IECBanco de Dados I
Aula 17 – Otimização Modelo Relacional
Turmas: Sistemas de Informação
Professora: André Luiz da Costa Carvalho
E-mail: [email protected]
Site: http://bdufam.wordpress.com
Sumário
Técnicas de otimização de EsquemaTécnicas de otimização de Consultas
Introdução O primeiro lugar onde podemos fazer
Bancos de Dados melhores é na criação das tabelas (relações)
Com a aplicação rodando, mudar tableas pode levar à alterações em todos os programas que a usam
Importante acertar na primeira tentativa.
Alguns esquemas são melhores que outros Vejamos estes dois esquemas para informações
de pedidos feitos para compra de materiais: Fornece1(ID_forn,ID_mat,qtde,end_forn)
Fornece2(ID_forn,ID_part,qtde)Fornecedor(ID_forn,end_forn)
Vamos comparar estes dois esquemas no seguinte cenário: 100000 compras 2000 fornecedores Inteiros de 8 bytes e end_forn de 50 bytes.
1 - Espaço Segundo esquema usa espaço extra
para o ID_forn redundante. 2000 x 8 = 16 mil bytes
Contudo, economiza nos endereços 2000 endereços vs 100000 do primeiro. 98000 x 50 = 4.950.000 bytes a menos Total 4.934.000 bytes a menos para o
segundo Só 5 megas?
Sim, mas ganho se manteria mesmo se aumentássemos para 1 bilhão de linhas
2 – Preservação da Informação Imaginem que um fornecedor X entregou
todos os pedidos pendentes. Faz sentido que as linhas pertinentes a
ele sejam deletadas. Dessa forma, no esquema 1, a
informação de endereço de X seria perdida junto.
Então 1 é sempre pior? Nem sempre
3 - Performance Se você tem uma necessidade constante
de saber o endereço do fornecedor de um dados pedido/peça, ele pode ser melhor. Especialmente se houverem poucas
inserções. Se houverem novas inserções
constantes, o endereço extra em cada pedido vai ser trabalho extra. Então, cada esquema pode ser útil
dependendo do caso.
Normalização Esquema 1 é não normalizado,
enquanto o esquema 2 é normalizado. Dependência funcional
X são atributos de R, A é um atributo específico de R
X -> A X determina A Se duas instâncias diferentes tem o mesmo valor de X,
elas terão o mesmo valor para A Isto é mais interessante se A não é um atributo de X
Como assim? Cada fornecedor tem um endereço
Cada ID_forn determina o endereço
Particionamento Vertical Banco: numCli, saldo e endereco
Dependências: numCli->endereco e numCli->saldo
Duas formas de fazer o esquema respeitando as dependências (numCli, endereco, saldo) (numCli, endereco)
(numCli,saldo) Qual é melhor?
Depende das consultas!
Banco Endereço é usado geralmente uma vez
por mês. Para mandar contas.
Saldo, em contrapartida é usado o tempo todo
Tabela (numCli,saldo) seria menor, o que traria benefícios Índices de cluster esparsos podem ser
menores. Mais pares numCli,saldo caberão na
memória Consulta que precisar ler todos saldos leria
menos blocos
11
Perfomance R (X,Y,Z)
X inteiro YZ são strings
Consulta de Scan Particionamento Vertical ruim quando todos
atributos são acessados. Melhora quando só dois são acessados.
0
0.005
0.01
0.015
0.02
No Partitioning -XYZ
VerticalPartitioning - XYZ
No Partitioning -XY
VerticalPartitioning - XY
Thro
ugpu
t (qu
erie
s/se
c)
Cenário 2 numCli, endereco, cep, saldo Este esquema faz sentido?
(numCli,endereco) (numCli,cep) (numCli,saldo)
Separar CEP e endereço não parece uma boa idéia, já que eles devem ser sempre acessados junto.
Quando particionar: Acessos costumam ser em um dos conjuntos
de atributos, nunca entre atributos de ambos. Atributos Y e Z são grandes (1/3 do tamanho
de um bloco)
Desnormalização As vezes, pode ser interessante ter uma
informação não relacionada diretamente em uma relação, se houverem muitas consultas que projetem esta informação. Ou seja, se tiver que fazer vários joins para
acessar a informação. Joins são caros.
Pode valer a pena ter informação duplicada para agilizar.
14
Desnormalização Consulta: encontrar itens cujo fornecedor fica na
Europa. Normalizado precisa de 4 joins Desnormalizado: adiciona nome daregião ao item
(foreign key denormalization) Performance melhora 30%
0
0.0005
0.001
0.0015
0.002
normalized denormalized
Thro
ughp
ut (Q
ueri
es/s
ec)
Manutenção de agregação Consultas com SUM, AVERAGE e afins
podem ser muito caras. Pode valer a pena guardar visões
materializadas destas consultas. Espaço extra será usado. Cada insert gerará custos extras de
atualização da visão. Vale a pena se houverem mais consultas
que inserções. Pode-se criar tabelas redundantes com
gatilhos também.
Manutenção de agregação
Domínios dos atrinutos Sempre prefira Integer a Float se
possível. Float força range queries. Ex: Select nota from aluno where nota = 5
viraSelect nota from aluno where nota >=4.999 and nota <=5.001
Atributos que variam de tamanho: Use tipos variáveis. Varchar melhor que char se tamanho do
texto variar muito. Porém updates podem causar
fragmentação se valor novo não couber no bloco
Otimização de Consultas
Otimização de Consultas Sempre começe a otimização pelo que
pode ser 100% benéfico. Criar índices, mudar o esquema, criar
visões, podem gerar custos novos. Reescrever consultas para ser mais rápidas
só traz benefícios
20
Base de exemplo
funcionario(cpf, nome, dept, salario, numamigos);estudante(cpf, nome, curso, periodo);dept(dept, gerente, localizacao);
clustered index i1 on funcionario (cpf);nonclustered index i2 on funcionario (nome);nonclustered index i3 on funcionario (dept);
clustered index i4 on estudante (cpf);nonclustered index i5 on estudante (nome);
clustered index i6 on dept (dept); 100000 tuplas funcionario, 100000 estudante, 10
departments; Cold buffer
21
Elimine DISTINCTs desnecessários Query: Encontrar empregados do
departamento “ti”. Sem duplicatas.SELECT distinct cpfFROM funcionarioWHERE dept = ‘ti’
DISTINCT desnecessário, já que cpf é chave de funcionario
22
Elimine DISTINCTs desnecessários Query: Encontrar cpf dos funcionarios de
algum departamento sem duplicatas.SELECT DISTINCT ssnumFROM employee, techWHERE employee.dept = tech.dept
Distinct necessário?
23
DISTINCT desnecessário Como dept é chave de dept, cada
funcionário vai casar com um único registro de dept.
Cpf é chave do funcionário, então será 1 para um, sem precisar de distinct.
24
Generalizando Relacionamento entre DISTINCT, chaves e
joins pode ser generalizado: Uma tabela T é chamada de privilegiada se os
campos retornados pelo select contém uma chave de T
Dado R, uma tabela não privilegiada. Se R é joinada através de uma chave a outra tabela S, diz se que R alcança S (reaches).
Alcance é transitivo. Se R1 alcança R2 e R2 alcança R3, então R1 alcança R3.
25
Reaches: Teorema Não haverão duplicatas, mesmo sem
distinct, se uma das duas condições for válida: Toda tabela no FROM é privilegiada Toda tabela não-privilegiada alcança ao
menos uma tabela privilegiada.
26
Reaches Se toda relação é privilegiada então não
haverão duplicatas Chaves da relação estão no from.
Dada uma relação T que não é privilegiada mas alcança ao menos uma relação privilegiada R. O Link entre T e R garante que cada
combinação de registros privilegiados é juntada com pelo menos um registro de T.
27
Reaches: Exemplo 1
O mesmo funcionário pode casar com vários deptos (gerente não é chave), então cpf pode aparecer várias vezes.
Dept não alcança a a relação privilegiada funcionário.
SELECT funcionario.cpfFROM funcionario, dept
WHERE funcionario.gerente = dept.gerente
28
Reaches: Exemplo 2
Cada valor de cpf seria acompanhado de um valor de departamento diferente, já que dept.nome é chave de dept.
Ambas relações são privilegiadas.
SELECT cpf, dept.nomeFROM funcionario, dept
WHERE funcionario.gerente = dept.gerente
29
Reaches: Exemplo 3
Estudante é privilegiado Funcionário não alcança estudante (Nome
não é chave) DISTINCT é necessário.
Só em caso de nomes repetidos.
SELECT estudante.cpfFROM estudante, funcionario, dept
WHERE estudente.nome = funcionario.nome AND funcionario.dept = dept.nome;
30
Queries – Subconsultas correlacionadas
Original:select cpffrom funcionario e1 where salario = (select max(salario) from funcionario e2 where e2.dept = e1.dept);
Reescrita:select max(salario) as maiorsalario, deptinto TEMP from funcionario group by dept;
Select cpffrom funcionario, TEMPwhere salario = maiorsalarioand funcionario.dept = temp.dept;
31
Subconsultas relacionadas SQL Server 2000 vai bem (usa hashjoin ao invés
de repetição aninhada)
-10
0
10
20
30
40
50
60
70
80
correlated subquery
Thro
ughp
ut im
prov
emen
t per
cent
SQLServer 2000Oracle 8iDB2 V7.1
> 10000> 1000
32
Manutenção de Agregação
pedidos( numPedido, itemnum, qtde, idloja, idvend);create clustered index i_pedr on pedidos(itemnum);
store( idloja, nome);
item(itemnum, preco);create clustered index i_item on item(itemnum);
vendOtimo( idvend, total);
lojaOtimo( idloja, total);
1000000 pedidos, 10000 lojas, 400000 items; Cold buffer
33
Manutenção de Agregação -- triggersTriggers para Manutenção de Agregação
create trigger atualizaVendOtimo on pedidos for insert asupdate vendOtimoset qtde =
(select vendOtimo.total+sum(inserted.qtde*item.preco)from inserted,itemwhere inserted.itemnum = item.itemnum)
Where idvend = (select idvend from inserted) ;
create trigger atualizaLojaOtimo on pedidos for insert asupdate lojaOtimoset qtde =
(select lojaOtimo.total+sum(inserted.qtde*item.preco) from inserted,item where inserted.itemnum = item.itemnum)
where idloja = (select idloja from inserted)
34
Aggregate Maintenance -- transações
Inserçõesinsert into pedidos values (1000350,7825,562,'xxxxxx6944',’jose');
Consultas (sem e com tabelas redundantes)select pedidos.vendid, sum(pedidos.qtde*item.preco)from pedidos,itemwhere pedidos.itemnum = item.itemnumgroup by pedidos.vendid;
vs. select * from vendOtimo;
select loja.nome, sum(pedidos.qtdey*item.preco)from pedidos,item, lojawhere pedidos.itemnum = item.itemnum and pedidos.idloja =
loja.idlojagroup by loja.idloja;
vs. select * from lojaOtimo;
35
Manutenção de integração Gatilhos para manutenção Se tem muitas consultas e poucas
inserções, então vale a pena.pect. of gain with aggregate maintenance
21900
31900
- 62.2-50000
5000100001500020000250003000035000
insert vendor total store total