Você está na página 1de 54

Processamento de Consultas

2COP325
Prof. Daniel S. Kaster
Departamento de Computao
Universidade Estadual de Londrina
dskaster@uel.br

Introduo

O processamento de consultas em um SGBD engloba vrias


operaes
O objetivo primrio traduzir a consulta fornecida pela
aplicao cliente em cdigo executvel utilizando os recursos
do SGBD
O objetivo secundrio, mas no menos importante, gerar um
cdigo eficiente para a consulta

Prof. Daniel S. Kaster

Etapas do processamento de consultas


Consulta em linguagem
de alto nvel
INTERPRETADOR
Leitura, parsing e validao

OTIMIZADOR LGICO
Reescrita de consultas

GERADOR DE CDIGO
Algoritmos e empacotamento

EXECUTOR
Processamento de transaes
Resultado

Prof. Daniel S. Kaster

Etapas do processamento de consultas


Consulta em linguagem
de alto nvel
INTERPRETADOR
Leitura, parsing e validao

OTIMIZADOR LGICO
Reescrita de consultas

GERADOR DE CDIGO
Algoritmos e empacotamento

EXECUTOR
Processamento de transaes
Resultado

Prof. Daniel S. Kaster

Interpretador

SQL
Analisador Lxico

Analisador Sinttico

Analisador Semntico

Parsing da consulta (tokens)

Verificao da estrutura da consulta


Verificao dos nomes de tabelas,
nomes e tipos dos atributos e
expresses

rvore de consulta cannica


Acessa o catlogo do banco!

Prof. Daniel S. Kaster

rvore de consulta

Uma rvore de consulta uma representao de uma sentena


SQL forma uma rvore de operadores, na qual:

Folhas so as relaes de entrada;

Ns internos so as operaes; e

A execuo ocorre de baixo para cima, onde cada operao gera um


resultado intermedirio (tabela), que serve de entrada para a operao
diretamente acima na rvore de consulta.

Lembrete: cada operao relacional recebe uma relao como


entrada e gera outra como sada

Prof. Daniel S. Kaster

rvore de consulta cannica

A rvore de consulta cannica corresponde diretamente


forma como a consulta foi escrita pelo usurio

Uma nica expresso para todo o bloco


SELECT-FROM-WHERE-GROUP BY-HAVING

Prof. Daniel S. Kaster

Tratamento de subconsultas

Em geral, subconsultas so avaliadas separadamente


SELECT pnome, unome
FROM empregado
WHERE salario > ( SELECT MAX(salario)
FROM empregado
WHERE dnum = 5 )
c MAX(salario)(dnum = 5 (empregado))
pnome, unome (salario > c (empregado))

Prof. Daniel S. Kaster

Etapas do processamento de consultas


Consulta em linguagem
de alto nvel
INTERPRETADOR
Leitura, parsing e validao

OTIMIZADOR LGICO
Reescrita de consultas

GERADOR DE CDIGO
Algoritmos e empacotamento

EXECUTOR
Processamento de transaes
Resultado

Prof. Daniel S. Kaster

Otimizador lgico

A etapa de otimizao tem por objetivo gerar uma rvore de


consulta equivalente inicial, mas com uma execuo mais
eficiente.
uma forma para otimizao de cdigo dos programas em
tempo de execuo.
A otimizao lgica visa explorar as propriedades algbricas
das consultas relacionais.

Prof. Daniel S. Kaster

10

Na verdade, otimizao
no termo mais adequado...

Embora seja comumente usada, a palavra otimizao no a


mais adequada, pois procura-se uma melhora razovel no
desempenho da execuo da consulta, mas no
necessariamente tima, pois:

Tempo necessrio para chegar a uma soluo tima torna o processo


impraticvel; e
O otimizador de consultas um programa, portanto, limitado aos
dados disponveis no catlogo do banco.

Prof. Daniel S. Kaster

11

Componentes do otimizador lgico

rvore de consulta cannica


Gerador de planos lgicos

Reescrita de consultas usando


propriedades algbricas

Avaliador de planos

Estimativas e comparao de
custos

rvore de consulta otimizada

Acessa o catlogo do banco!


(Estatsticas)

Prof. Daniel S. Kaster

12

Gerador de planos lgicos

Note que a etapa de otimizao tem que gerar uma rvore de


execuo equivalente inicial, ou seja, com o mesmo
resultado.
Portanto, esse processamento est limitado s transformaes
possveis em uma consulta relacional.
De acordo com o significado de cada operao foi definido um
conjunto de regras de transformao, seguindo a forte
fundamentao matemtica do modelo relacional.

Prof. Daniel S. Kaster

13

Regras de equivalncia relacionais

R1) Cascateamento de
c1 AND c2 AND ... AND cn (R) c1(c2(...(cn(R))...))

R2) Comutatividade de
c1(c2(R)) c2(c1(R))

R3) Cascateamento de
list1(list2(...(listn(R))...)) list1(R)

R4) Comutatividade entre e


A1, A2, ..., An(c(R)) c(A1, A2, ..., An(R))

R5) Comutatividade de e
RSSR

SS

Prof. Daniel S. Kaster

14

Regras de equivalncia relacionais (cont.)

R6) Comutatividade de com


c(R

S ou c(R

S) (c1(R))

R7) Comutatividade de com


L(R

S) c(R)

(ou , , )

S) L((A1,...,An,A1,...,An(R))

(c2(S))

(ou )
(B1,...,Bn,B1,...,Bn(S))

R8) Comutatividade de operaes de conjunto


e so comutativas, mas no

R9) Associatividade de , , e
Seja a operao: (R S) T R (S T)

R10) Converso de (c(RS)) em (R


Prof. Daniel S. Kaster

S)

15

Algoritmo geral de otimizao lgica

Fundamentos do algoritmo:

Aplicar operaes SELECT e PROJECT sempre que possvel antes de


operaes binrias, pois as operaes binrias so geralmente funes
multiplicativas nos tamanhos das entradas;
Substituir conjuntos de operaes equivalentes por operaes menos
custosas; e
Definir uma ordem adequada para execuo de operaes binrias,
pois a ordem pode alterar significativamente o custo.

Prof. Daniel S. Kaster

16

Passos do algoritmo

1) Separe selees conjuntivas em um cascateamento de


selees, para facilitar a movimentao das selees (R1)
2) Movimente as selees o mais para baixo possvel na rvore
de consulta (R2, R4, R6)
3) Rearranje os ns folha, para otimizar as operaes binrias,
posicionando como folhas as relaes com operaes de
seleo mais restritivas (R5, R8, R9)
4) Substitua operaes c(R S) por (R

S) (R10)

5) Movimente as projees o mais para baixo possvel na rvore


de consulta (R3, R4, R7)
6) Identifique subrvores com grupos de operaes que podem
ser executadas por um nico algoritmo (empacotamento)
Prof. Daniel S. Kaster

17

Exemplo de otimizao lgica

Considerando o exemplo empresa, montar a rvore de consulta


inicial e aplicar o algoritmo geral de otimizao para a consulta
a seguir
SELECT e.pnome, e.snome
FROM empregado e, trab_em t, projeto p
WHERE p.pnome = aquarius AND p.pnum = t.pnum
AND e.CPF = t.CPF AND e.dt_nasc > 1957-12-31;

Lembrete: pnum, pnome e CPF so nicos

Prof. Daniel S. Kaster

18

Avaliador de planos

A etapa de otimizao visa estimar o gasto ou custo de uma


consulta, em termos de tempo de execuo e consumo de
recursos, com base em estatsticas armazenadas no catlogo
do banco
Essa estimativa considera uma srie de parmetros e tem duas
variaes:

Minimizar o tempo de resposta de consultas

Maximizar o throughput de transaes


Os objetivos destas duas variaes, em geral, so conflitantes
em um ambiente multiusurio

Prof. Daniel S. Kaster

19

Parmetros para estimar custos

Os parmetros de custo envolvem vrios fatores, como:

Armazenamento intermedirio (temporrio)

Processamento em memria

Quantidade de memria

Comunicao

Acesso a disco

Os otimizadores de SGBD convencionais priorizam a


minimizao de acessos a disco

Prof. Daniel S. Kaster

20

Estatsticas no catlogo do BD

O avaliador de planos depende de estatsticas sobre os objetos


do banco de dados para estimar os custos das operaes

Nmero de registros (tuplas) r

Tamanho do registro R

Nmero de blocos b

Tamanho do bloco B

Fator de bloco (Blocking factor) bfr = B / R

N nveis do ndice x

N blocos de primeiro nvel ou nvel base (folhas) blevel1

Seletividade: frao dos registros que satisfazem uma condio sl


(chave sl = 1 / r)
Cardinalidade da seleo: quantidade de registros que satisfazem uma
condio s = sl * r (chave s = 1)
Prof. Daniel S. Kaster

21

Estatsticas de seletividade

A previso de seletividade baseada na cardinalidade da


relao resultante, portanto, depende do operador usado,
sendo diferente para igualdade e intervalos

OBS: alguns autores definem sl = 1 (s / r)

Estas estatsticas so associadas a cada atributo de cada


relao

Exige espao de armazenamento, manuteno peridica e consulta


durante o processo de otimizao de consultas

Prof. Daniel S. Kaster

22

Tipos de estatsticas de seletividade

Constante (chute)

s = 0,1 * r

(o chute 10% da tabela de entrada)

Estimativa ruim, porm no exige armazenamento ou manuteno

Homognea (uniforme) atributos de domnios discretos ou


discretizados

s = 1 / (maior_valor - menor_valor)
Embora esta opo seja melhor que a constante, considerar distribuio
uniforme, em geral, ainda uma estimativa ruim
Exige armazenar apenas 2 valores por atributo e a manuteno
simples

Prof. Daniel S. Kaster

23

Tipos de estatsticas de seletividade (cont.)

Por histograma (atributos discretos):

Permite melhor preciso na estimativa de seletividade, porm, em geral,


exige um considervel espao de armazenamento por atributo
Alternativa: compactao do histograma

Histograma com igual espaamento (agrupa uma quantidade


estabelecida de bins contguos)
Histograma com igual densidade (agrupa bins contguos cujos
valores so prximos)

Por funo de distribuio (atributos contnuos)

Gaussiana, Poisson, Chi-quadrado.

Seletividade para igualdade: valor da funo no valor do atributo.

Seletividade para intervalo: valor da integral da funo no intervalo


(obtendo a rea sob a curva).
Prof. Daniel S. Kaster

24

Etapas do processamento de consultas


Consulta em linguagem
de alto nvel
INTERPRETADOR
Leitura, parsing e validao

OTIMIZADOR LGICO
Reescrita de consultas

GERADOR DE CDIGO
Algoritmos e empacotamento

EXECUTOR
Processamento de transaes
Resultado

Prof. Daniel S. Kaster

25

Gerador de cdigo

A etapa de gerao de cdigo identifica quais os algoritmos que


podem ser usados para resolver cada operao, considerando
os ndices existentes e as condies que aparecem nos
predicados das operaes
A escolha dos algoritmos visa gerar um plano de execuo
fsico de custo mnimo, portanto tambm envolve otimizao
Por isso, na sequncia sero discutidos os principais algoritmos
para as diversas operaes relacionais e seus custos

Prof. Daniel S. Kaster

26

Algoritmos

Ordenao externa

Seleo

Juno

Projeo

Operaes de conjuntos

Funes de agregao

Prof. Daniel S. Kaster

27

Ordenao externa

Ordenao: muito usada

ORDER BY

Junes

Eliminao de duplicados

externa porque o arquivo no cabe na memria

Derivado do algoritmo de ordenao merge sort

Prof. Daniel S. Kaster

28

Algoritmo de ordenao externa

Considerando um buffer com bbuffer blocos


1) Enquanto no fim-de-arquivo (sorting)
Leia os prximos b

buffer

blocos do arquivo, ordene os registros desta

parte do arquivo e reescreva-os em outra rea do disco

2) Enquanto no ordenado (merge)


Tome bbuffer 1 partes ordenadas, mescle-os e armazene o resultado no
ltimo bloco do buffer, lendo os blocos das partes ordenadas
consecutivamente (blocos do resultado idem)

COrdExt = 2 * (b + b*loggmnr),

onde gm=(bbuffer - 1) o grau de merge e nr= b/bbuffer o n de partes


ordenadas
Prof. Daniel S. Kaster

29

Seleo

A operao de seleo muito utilizada para acesso a dados


em disco

Pode reduzir a quantidade de acessos

H inmeras variaes de algoritmos de seleo, dependendo


da condio imposta, da organizao em disco da relao de
entrada, da disponibilidade de ndices e dos tipos destes
ndices

Prof. Daniel S. Kaster

30

Algoritmos de seleo

S1: Busca sequencial

Se a relao de entrada est ordenada segundo o atributo utilizado na


seleo, a condio baseada em igualdade e o atributo chave (ex:
idade=20(Pessoa), Pessoa est ordenada por idade e idade chave)

Se a relao de entrada est ordenada segundo o atributo utilizado na


seleo, a condio baseada em igualdade e o atributo no chave
(ex: idade=20(Pessoa), Pessoa ordenada por idade e idade no chave)

CS1 = b/2

CS1 = b/2 s/Bfr - 1

Se a relao de entrada est ordenada segundo o atributo utilizado na


seleo e a condio baseada em intervalo, independente se o
atributo chave ou no (ex: idade>20(Pessoa))

CS1 = b/2 ; pode-se considerar este algoritmo para o caso


acima
Prof. Daniel S. Kaster

31

Algoritmos de seleo (cont.)

S1: Busca sequencial (cont.)

Se a relao de entrada no est ordenada segundo o atributo utilizado


na seleo, a condio baseada em igualdade e o atributo chave
(ex: idade=20(Pessoa), Pessoa no ordenada por idade e idade chave)

Se a relao de entrada no est ordenada segundo o atributo utilizado


na seleo, a condio baseada em igualdade e o atributo no
chave (ex: idade=20(Pessoa), Pessoa no ordenada por idade e idade
no chave)

CS1 = b/2 se achar e CS1 =bse no achar

CS1 = b

Se a relao de entrada no est ordenada segundo o atributo utilizado


na seleo e a condio baseada em intervalo, independente se o
atributo chave ou no (ex: idade>20(Pessoa))

CS1 = b
Prof. Daniel S. Kaster

32

Algoritmos de seleo (cont.)

S2: Busca binria

Se a relao de entrada est ordenada segundo o atributo utilizado na


seleo, a condio baseada em igualdade e o atributo chave (ex:
idade=20(Pessoa), Pessoa est ordenada por idade e idade chave)

CS2 = log2b

Se a relao de entrada est ordenada segundo o atributo utilizado na


seleo, a condio baseada em igualdade e o atributo no chave
(ex: idade=20(Pessoa), Pessoa ordenada por idade (no chave)

CS2 = log2b s/Bfr - 1

Prof. Daniel S. Kaster

33

Algoritmos de seleo (cont.)

S3: ndice primrio

Se existe um ndice primrio no atributo utilizado na seleo (o que


implica que a relao est ordenada segundo este atributo e que este
atributo chave) e a condio baseada em igualdade

CS3 = x + 1

Se existe um ndice primrio no atributo utilizado na seleo e a


condio baseada em intervalo

CS3 = x + s/Bfr

Prof. Daniel S. Kaster

34

Algoritmos de seleo (cont.)

S5: ndice clustering

Se existe um ndice clustering no atributo utilizado na seleo (o que


implica que a relao est ordenada segundo este atributo e que este
atributo no chave), independente da condio ser baseada em
igualdade ou intervalo

CS5 = x + s/Bfr

Prof. Daniel S. Kaster

35

Algoritmos de seleo (cont.)

S6: ndice secundrio (B+-tree)

Se existe um ndice secundrio no atributo utilizado na seleo (o que


implica que a relao no est ordenada segundo este atributo), a
condio baseada em igualdade e o atributo chave

Se existe um ndice secundrio no atributo utilizado na seleo, a


condio baseada em igualdade e o atributo no chave

CS6 = x + 1

CS6 = x + s

Se existe um ndice secundrio no atributo utilizado na seleo, a


condio baseada em intervalo, independente se o atributo chave
ou no

CS6 = x + blevel1 * (s/r) - 1 s, onde (s/r) define a proporo estimada


de tuplas que satisfazem a condio
OBS: deve-se ordenar os rowIds, para evitar swaps
desnecessrios
Prof. Daniel S. Kaster

36

Algoritmos de seleo (cont.)

S7: Seleo conjuntiva (and) usando um ndice simples

Utilize o ndice na expresso correspondente, recupere os registros que


a satisfazem e teste as outras condies atravs de uma varredura
sequencial em memria

S8: Seleo conjuntiva usando um ndice composto

CS7 = custo_ndice1 + custo_teste_condio2

CS8 = custo_ndice (considere a seletividade da conjuno sconj)

S9: Seleo conjuntiva pela interseo de ponteiros, usando


mais de um ndice simples

CS9 = custo_ndice*1 + custo_ndice*2 + custo_interseo + sconj


* Nesse caso, considera-se apenas os custos internos aos
ndices, i.e. sem considerar o acesso adicionais a blocos de
dados, pois o acesso s tuplas est representado por sconj
Prof. Daniel S. Kaster

37

Algoritmos de seleo (cont.)

S10: Seleo disjuntiva

Se houver ndices para TODOS os atributos da expresso, unio de


ponteiros

CS10 = custo_ndice*1 + + custo_ndice*n + custo_unio + sdisj


* Considera-se apenas os custos internos aos ndices; o
acesso s tuplas est representado por sdisj

Caso contrrio, busca linear

CS10 = b

Prof. Daniel S. Kaster

38

Exemplo seleo: estatsticas

Relao empregado: 10.000 registros em 2.000 blocos, com


Bfr = 5 reg/bloco
ndice clustering em salrio, com xsalario= 3 nveis, e
cardinalidade de seleo mdia ssalario= 20.
ndice secundrio no atributo chave CPF com xCPF= 4 e sCPF= 1.
ndice secundrio no atributo no chave dnum com xdnum= 2,
nmero de blocos de primeiro nvel no ndice bl1= 4 e ddnum= 125
valores distintos para dnum. (calcular sdnum)
ndice secundrio em sexo com xsexo= 1. H apenas dsexo= 2
valores distintos (calcular ssexo)
Prof. Daniel S. Kaster

39

Exemplo seleo: operaes

Op1: CPF = 123456789 (empregado)

Op2: dnum > 5 (empregado)

Op3: dnum = 5 (empregado)

Op4: dnum = 5 AND salario > 3000 and sexo = f (empregado)

Op1: S1 ou S6

Op2: S1 ou S6

Op3: S1 ou S6

Op4: S1, S4 (salario), S6 (dnum), S6 (sexo) + linear em memria para


testar as demais condies
Prof. Daniel S. Kaster

40

Juno

Operao bastante custosa e frequentemente usada


Tomaremos a equijoin como exemplo, mas o processamento
das demais junes semelhante
O fator de bloco da relao resultante tem que considerar que
as tuplas so a concatenao das tuplas das relaes de
entrada
A cardinalidade da relao resultante depende da condio de
juno

OBS: equijoins fazendo juno de chave primria com chave


estrangeira geram relaes cuja cardinalidade menor ou igual
cardinalidade da relao do lado da chave estrangeira (igual se os
atributos de juno no permitirem nulos)

Prof. Daniel S. Kaster

41

Algoritmos de juno

J1: Loops aninhados (nested-loops join / nested-blocks join)

J2: Loop simples (single-loop)

CJ2 = bouter + ( router * (custo_ndice))

J3: Sort-merge

CJ1 = bouter + ( bouter / (bbuffer 2) * binner )

CJ3 = br + bs (+ custo_ordenaes, se necessrio)

J4: Hash-join

semelhante ao loop simples, mas utiliza um ndice hash criado em


memria especialmente para executar a operao (esta estrutura
destruda ao final da execuo da operao)
til especialmente para executar junes de tabelas que no possuem
ndices (por exemplo, tabelas geradas por operaes anteriores)
Prof. Daniel S. Kaster

42

Exemplo juno: estatsticas

bbuffer = 7 blocos

departamento: rdep= 50 registros em bdep=10 blocos

empregado: remp= 6.000 registros; bemp= 2000 blocos

empregado tem ndice secundrio em CPF com xCPF= 4

departamento tem ndice secundrio em CPFger com xCPFger= 2

Prof. Daniel S. Kaster

43

Exemplo juno: operaes

Op1: empregado

Desempenho de J1

departamento

Efeitos da escolha da relao interna e externa e tamanho do buffer

CPF = CPFger

Empregado ou departamento como externa?

Efeitos do tamanho do buffer disponvel para a juno

Outer com 1 bloco: bR + ( bR* bS )

Outer com (bbuffer 2) blocos: bR + ( bR / bbuffer 2 * bS )

Desempenho de J2

Desempenho de J3

Prof. Daniel S. Kaster

44

Projeo

Variaes

Baseada em conjunto (set-based): elimina duplicados, o que,


tipicamente, implica em uma ordenao

Baseada em multiconjunto (bag-based): no elimina duplicados

Coerente com o modelo relacional


Coerente com a proposta da SQL

CP = b + (custo_ordenao_considerando_b' + b)

Onde b o nmero de blocos da relao aps a projeo dos atributos


Se a projeo inclui uma chave candidata da relao de entrada, pulase a eliminao de duplicados, eliminando o custo da ordenao
externa

Prof. Daniel S. Kaster

45

Operaes de conjuntos

Produto cartesiano

Utiliza loop aninhado

Unio, interseo e diferena de conjuntos

Utilizam variaes do sort-merge


Considerando tais operaes como set-based podem exigir a
eliminao de duplicados; considerando como bag-based, mantm-se
duplicados

Prof. Daniel S. Kaster

46

Funes de agregao

F1: Busca linear

CF1 = b

F2: ndice no atributo da funo agregao

min, max: elemento folha mais a esquerda ou mais a direita do ndice

Count, avg, sum: se o ndice for denso (fast-full scan)

CF2 = x (se for ndice denso) e CF2 = x + 1 (se for esparso)


CF2 = x + blevel1 - 1

F3: Group by

Opo 1: ordene pelo(s) atributo(s) de agrupamento e, em seguida,


calcule a funo de agregao para cada grupo

CF3 = custo_ordenao + b

Opo 2: utilize uma estrutura de dados em memria para guardar os


acumuladores
Prof. Daniel S. Kaster

47

Gerador de cdigo

rvore de consulta otimizada


Verificador de recursos disponveis

Empacotador

Verifica a disponibilidade de ndices,


formas de otimizao do acesso ao arquivo.

Verifica disponibilidade dos


recursos necessrios
Escolhe os algoritmos para
executar os conjuntos de operaes
Vai montar o agrupamentos dos

Plano de execuo

algoritmos que executam as operaes


solicitadas no comando

Prof. Daniel S. Kaster

48

Empacotador

o responsvel por gerar o cdigo contido no plano de


execuo fsico (caminhos de acesso)
Dada a rvore de execuo otimizada, o empacotador usa um
algoritmo para realizar vrias operaes subseqentes
A execuo de vrias operaes em um nico algoritmo pode
otimizar o desempenho da execuo

Exemplos: leitura + ordenao; leitura + seleo; leitura + seleo +


juno + projeo; ...

Prof. Daniel S. Kaster

49

Plano de execuo

Seqncia de operaes

Algoritmos e mtodos de acesso (ndices)

Materializao vs. Pipelining

Left/right-deep join query trees

Facilitar otimizao (ordem dos joins), diminuindo as possibilidades

Mais apropriado para pipelining

Tendo uma relao base (folha) como entrada, pode-se usar seus
mtodos de acesso (ndices)

Prof. Daniel S. Kaster

50

Pipelining usando iteradores

Evitar a materializao de resultados intermedirios em disco,


pois o custo muito alto
Iterator

Open( );

GetNext( );

Inicializa as estruturas de dados para realizar a operao.


Retorna a prxima tupla a ser processada e ajusta as
estruturas usadas ou NotFound se no h mais tuplas.

Close( );

Finaliza a operao e faz a limpeza do buffer.

Prof. Daniel S. Kaster

51

Exemplo: TableScan_Iterator
Open( ) {
b = primeiro bloco de R;
t = primeira tupla do bloco b;
}
GetNext ( ) {
if (t == NULL) { // foi a ltima tupla do bloco b
b = prximo bloco de R;
if (b == NULL) // no h mais blocos
return NotFound;
else
t = primeira tupla de b;
}
oldt = t;
t = prxima tupla de b;
return oldt;
}
Close() {
}

Prof. Daniel S. Kaster

52

Etapas do processamento de consultas


Consulta em linguagem
de alto nvel
INTERPRETADOR
Leitura, parsing e validao

OTIMIZADOR LGICO
Reescrita de consultas

GERADOR DE CDIGO
Algoritmos e empacotamento

EXECUTOR
Processamento de transaes
Resultado

Prof. Daniel S. Kaster

53

Executor

Mquina dataflow com processamento de transaes

Prof. Daniel S. Kaster

54

Você também pode gostar