A Impedância, o Mapeamento Objeto Relacional e Implementações – Parte III

Bom Dia Pessoal,

Por conta das correrias de fim de ano, não consegui entrar em 2010 sem "zerar" minha dívida de artigos de 2009. Não é bom deixar dívidas de um ano para o outro, mas como acabei não dando conta, estou prosseguindo com essa terceira parte a representação de mecanismos de herança para bancos de dados relacionais. Nas partes I e II, restringi-me apenas às representações lógicas padrão (uma tabela para toda a herança, uma tabela para cada classe e uma tabela para cada classe concreta). Tais representações são diretamente mapeáveis para um modelo físico. Abordei também como uma situação de negócio pode comprometer ou justificar a escolha de uma ou outra abordagem, bem como um comparativo dos pontos fortes e fracos de cada representação. Nessa última parte, mostrarei algumas implementações físicas não triviais para lidar com a herança.

Por ser especialista em SQL Server, focarei as implementações voltadas para esse SGBD (em especial o 2008). Como as opções para esse SGBD são relativamente variadas, nesse artigo falarei especificamente sobre uma implementação que utiliza o conceito de Sparse Columns.

Utilizarei exatamente os mesmos exemplos do último artigo, ou seja, após as alterações negociais. Abaixo o diagrama de classes:

A notação de Peter Chen simplificada é apresentada abaixo:

O recurso Sparse Columns

Aos fãs do mapeamento da herança em uma única tabela, a funcionalidade Sparse Columns é sem dúvida um ótimo recurso. O grande dilema da implementação em uma única classe é que se as classes forem muito diferentes, ou seja, possuírem muitas características privadas, a tabela ficará com uma quantidade de elementos nulos muito grande provocando muito desperdício de espaço e dificuldades nas regras de validação de inserção e atualização de registros. O uso do recurso de Sparse Columns se propõe a resolver o problema de espaço, de validação das regras de inseração e atualização além de facilitar algumas consultas. Esse recurso tem as seguintes características:

  • Valores nulos não requerem espaço quando forem armazenados
  • Valores não nulos requerem espaço adicional para armazenamento
  • Valores fixos requerem 4 bytes extras
  • Valores variáveis requerem dois bytes adicionais

Para utilizar esse recurso, será criada uma única tabela com o mapeamento de toda a herança.

— Criação da Tabela
CREATE TABLE Colaborador (
    Matricula INT NOT NULL,
    Nome VARCHAR(50) NOT NULL,
    Gerencia VARCHAR(80) NOT NULL,
    Cargo VARCHAR(50) NOT NULL,
    Tipo INT NOT NULL,
    NumeroPis CHAR(11) SPARSE NULL,
    EmpresaContratante VARCHAR(80) SPARSE NULL,
    DataContratacao DATE SPARSE NULL,
    Curso VARCHAR(80) SPARSE NULL,
    Faculdade VARCHAR(80) SPARSE NULL,
    PrevisaoTermino DATE SPARSE NULL,
    TemaMonografia VARCHAR(80) SPARSE NULL,
    LinkAcesso VARCHAR(100) SPARSE NULL,
    Projeto VARCHAR(80) SPARSE NULL,
    Especialidade VARCHAR(80) SPARSE NULL,
    Detalhes XML COLUMN_SET FOR ALL_SPARSE_COLUMNS)

Todas as colunas que são potencialmente nulas foram atribuídas como SPARSE. Ao final foi declarada uma coluna do tipo XML com uma definição "COLUMN_SET FOR ALL_SPARSE_COLUMNS". Comentarei sobre essa coluna posteriormente. O próximo passo é criar as regras de validação através de CHECK CONSTRAINTs. A regra a seguir especifica que dependendo do tipo, apenas as colunas corretas podem ser preenchidas.

ALTER TABLE Colaborador
ADD CONSTRAINT CKTipoColaborador CHECK (

    — Tipo 1 -> Efetivo
    (Tipo = 1 AND (
        NumeroPis IS NOT NULL AND
        EmpresaContratante IS NULL AND
        DataContratacao IS NULL AND
        Curso IS NULL AND
        Faculdade IS NULL AND
        PrevisaoTermino IS NULL AND
        TemaMonografia IS NULL AND
        LinkAcesso IS NULL AND
        Projeto IS NULL AND
        Especialidade IS NULL)) OR

    — Tipo 2 -> Terceirizado
    (Tipo = 2 AND (
        NumeroPis IS NULL AND
        EmpresaContratante IS NOT NULL AND
        DataContratacao IS NOT NULL AND
        Curso IS NULL AND
        Faculdade IS NULL AND
        PrevisaoTermino IS NULL AND
        TemaMonografia IS NULL AND
        LinkAcesso IS NULL AND
        Projeto IS NULL AND
        Especialidade IS NULL)) OR

    — Tipo 3 -> Estagiário
    (Tipo = 3 AND (
        NumeroPis IS NULL AND
        EmpresaContratante IS NULL AND
        DataContratacao IS NULL AND
        Curso IS NOT NULL AND
        Faculdade IS NOT NULL AND
        PrevisaoTermino IS NOT NULL AND
        TemaMonografia IS NULL AND
        LinkAcesso IS NULL AND
        Projeto IS NULL AND
        Especialidade IS NULL)) OR

    — Tipo 4 -> Estagiário Projeto Final
    (Tipo = 4 AND (
        NumeroPis IS NULL AND
        EmpresaContratante IS NULL AND
        DataContratacao IS NULL AND
        Curso IS NOT NULL AND
        Faculdade IS NOT NULL AND
        PrevisaoTermino IS NOT NULL AND
        TemaMonografia IS NOT NULL AND
        LinkAcesso IS NOT NULL AND
        Projeto IS NULL AND
        Especialidade IS NULL)) OR

    — Tipo 5 -> Consultor Externo
    (Tipo = 5 AND (
        NumeroPis IS NULL AND
        EmpresaContratante IS NULL AND
        DataContratacao IS NULL AND
        Curso IS NULL AND
        Faculdade IS NULL AND
        PrevisaoTermino IS NULL AND
        TemaMonografia IS NULL AND
        LinkAcesso IS NULL AND
        Projeto IS NOT NULL AND
        Especialidade IS NOT NULL)))

A próxima etapa é inserir alguns colaboradores para posteriormente visualizarmos o que o recurso de sparse columns pode oferecer.

— Insere um efetivo
INSERT INTO Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, NumeroPis)
VALUES (1,‘Cristiane’,‘RH’,‘Analista Jr.’,1,‘1235324’)

— Insere um terceirizado
INSERT INTO Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, EmpresaContratante, DataContratacao)
VALUES (2,‘Fausto’,‘Marketing’,‘Estoquista’,2,‘B2P Associados’,‘20080219’)

— Insere um estagiário
INSERT INTO Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, Curso, Faculdade, PrevisaoTermino)
VALUES (3,‘Carol’,‘Finanças’,‘Estagiário’,3,‘Contabilidade’,‘UFRS’,‘20110101’)

— Insere um estagiário de projeto final
INSERT INTO Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo,Curso, Faculdade, PrevisaoTermino, TemaMonografia, LinkAcesso)
VALUES (4,‘Flávia’,‘RH’,‘Estagiário’,4,‘Serviço Social’,‘UFP’,‘20100601’,‘Teorias Sociais no Mundo Corporativo – Um caso prático’,http://ufp.br/monografias/ss/06xttss/)

— Insere um consultor externo
INSERT INTO Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, Projeto, Especialidade)
VALUES (5,‘Elton’,‘Administrativo’,‘Consultor de Processos’,5,‘Mapeamento de Processos Organizacionais’,‘Estruturação de Processos’)

Agora que os registros estão devidamente realizados, vejamos o que uma simples consulta sobre a tabela de colaboradores pode retornar (apenas os três primeiros registros):

SELECT TOP 3 * FROM Colaborador

O resultado é exibido na tabela abaixo:

Matrícula Nome Gerência Cargo Tipo Detalhes
01 Cristiane RH Analista Jr. 1 <NumeroPis>1235324</NumeroPis>
02 Fausto Marketing Estoquista 2 <EmpresaContratante>B2P Associados</EmpresaContratante>
<DataContratacao>2008-02-19</DataContratacao>
03 Carol Finanças Estagiário 3 <Curso>Contabilidade</Curso>
<Faculdade>UFRS</Faculdade>
<PrevisaoTermino>20110101</PrevisaoTermino>

Alguns detalhes interessantes chamam a atenção nessa consulta:

  • Todas as colunas marcadas como SPARSE foram omitidas ainda que o SELECT * FROM tenha sido utilizado
  • A coluna "Detalhes" declarada como COLUMN_SET FOR ALL_SPARSE_COLUMNS retornou automaticamente todos os elementos preenchidos em um tipo de dados XML

Quando uma coluna é marcada como SPARSE "não haverá" consumo de espaço para valores nulos. O uso da propriedade SPARSE em conjunto com a propriedade COLUMN_SET FOR ALL_SPARSE_COLUMNS pode prover outros benefícios interessantes na elaboração de consultas já que haverá suporte a XML disponível. A consulta abaixo, por exemplo, retorna todos os efetivos e o número do PIS via XQuery:

SELECT
    Matricula, Nome, Gerencia, Cargo, Tipo,
    Detalhes.value(‘/NumeroPis[1]’,‘CHAR(11)’) As NumeroPis
FROM Colaborador
WHERE Tipo = 1

O fato da coluna NumeroPis ter sido omitida em uma instrução SELECT * FROM não significa que ela não possa ser mais acessada. É possível utilizá-la normalmente bastando referenciá-la. A mesma consulta pode ser reescrita de uma forma mais fácil.

SELECT Matricula, Nome, Gerencia, Cargo, Tipo, NumeroPis
FROM Colaborador
WHERE Tipo = 1

Embora a coluna "Detalhes" se assemelhe muito a uma coluna calculada, ao contrário destas, ela permite atualizações desde que em conformidade com as estruturas da tabela. Os comandos a seguir atualizam os dados da empresa contratante e da data de contratação do terceirizado Fausto.

— Faz a atualização
DECLARE @Alteracoes XML
SET @Alteracoes =
<EmpresaContratante>B2P Tecnologia</EmpresaContratante>
<DataContratacao>2009-02-19</DataContratacao>’

UPDATE Colaborador SET Detalhes = @Alteracoes
WHERE Matricula = 2

— Confere os dados
SELECT Matricula, EmpresaContratante, DataContratacao, Detalhes
FROM Colaborador
WHERE Matricula = 2

O resultado é exibido logo abaixo:

Matrícula EmpresaContratante DataContratacao Detalhes
02 B2P Tecnologia 19/02/2009 <EmpresaContratante>B2P Tecnologia</EmpresaContratante>
<DataContratacao>2009-02-19</DataContratacao>

Entretanto, para que essa atualização seja realmente efetiva, é necessário informar todas as características privadas da classe. Os comandos a seguir fazem apenas a atualização da data de contratação sem informar a empresa contratante.

— Faz a atualização
DECLARE @Alteracoes XML
SET @Alteracoes = ‘<DataContratacao>2009-06-19</DataContratacao>’

UPDATE Colaborador SET Detalhes = @Alteracoes
WHERE Matricula = 2

Uma mensagem de erro é gerada:

Msg 547, Level 16, State 0, Line 5
The UPDATE statement conflicted with the CHECK constraint "CKTipoColaborador". The conflict occurred in database "tempdb", table "dbo.Colaborador".
The statement has been terminated.

Como a coluna EmpresaContratante não foi informada, a atualização tentará deixar o seu valor como nulo. Felizmente a check constraint previniu que isso ocorresse relatando por tanto um erro de integridade já que não é possível um terceirizado (tipo 2) ter a empresa contratante não informada.

Quando utilizar o recurso Sparse Columns ?

O recurso Sparse Columns faz uma troca entre alguns bytes extras, overhead de CPU em troca de economia de espaço na presença de valores nulos. Seguindo essa premissa, o uso desse recurso deve considerar como primeiro princípio a forte presença de valores nulos em várias colunas. Se houver poucos valores nulos em poucas colunas, o uso desse recurso poderá incorrer em mais espaço e menos desempenho. Se houver muitos valores nulos em muitas colunas a utilização de sparse columns se torna bastante interessante, já que poderá incorrer em economias de espaço significativas.

No quesito modelagem, quanto mais numerosas forem as subclasses e quanto maior a quantidade de características privadas de cada uma dessas subclasses, mais recomendável será o uso de sparse columns, pois em um cenário desses, a quantidade de colunas nulas em várias colunas será certa. No exemplo em questão, um efetivo terá apenas o número do PIS informado, deixando nulas todas as demais colunas que representam características privadas como EmpresaContratante, DataContratacao, Curso, Faculdade, PrevisaoTermino, etc.

Um ponto que pode passar bem desapercebido é a presença de colunas do tipo VARCHAR. Essas colunas são otimizadas em relação ao armazenamento, pois, gastam dois bytes extras para controle, mas consomem apenas a área utilizada em oposição a tipos CHAR que embora não possuam os bytes de controle sempre gastam o tamanho proposto (mesmo que não tenha sido utilizado). A presença de muitas colunas VARCHAR não se beneficia tanto do recurso de Sparse Columns como as colunas de tamanho fixo (demonstrarei isso a seguir).

Outro ponto a ser analisado são as facilidades providas pela utilização da coluna Detalhes. Dependendo de como a aplicação está estruturada, ter a forte utilização de XML para mapear essas classes e efetuar a persistência pode ser compensador mesmo que o armazenamento não justifique sua implementação.

Comparação

Para que os conceitos sejam melhor fixadas nada melhor que um benchmark entre o uso da funcionalidade e uma solução padrão. O script a seguir distribui as frequências dos funcionários da FKW em 40% de efetivos, 30% de terceirizados, 20% de estagiários, 5% de estagiários de projeto final e 5% de consultores externos. Serão populados mil colaboradores em uma tabela que utiliza o recurso de sparse columns e uma que não utiliza. Embora os dados estejam repetidos, a idéia principal para comparação é volume e dados duplicados não inferem nessa comparação.

— Script de distribuição de frequência
— 40% efetivos
— 30% terceirizados
— 20% estagiários
— 05% estagiários de projeto final
— 05% consultores externos
— 100% -> 1000 registros

— Exclui todos os registros de colaboradores
DELETE FROM Colaborador

— Insere os efetivos
DECLARE @iterador INT = 1
WHILE @iterador <= 400
BEGIN
    INSERT INTO
Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, NumeroPis)
    VALUES (@iterador,‘Cristiane’,‘RH’,‘Analista Jr.’,1,‘1235324’)
    SET @iterador += 1
END

— Insere os terceirizados
WHILE @iterador <= 700
BEGIN
    INSERT INTO
Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, EmpresaContratante, DataContratacao)
    VALUES (@iterador,‘Fausto’,‘Marketing’,‘Estoquista’,2,‘B2P Associados’,‘20080219’)
    SET @iterador += 1
END

— Insere os estagiários
WHILE @iterador <= 900
BEGIN
    INSERT INTO
Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, Curso, Faculdade, PrevisaoTermino)
    VALUES (@iterador,‘Carol’,‘Finanças’,‘Estagiário’,3,‘Contabilidade’,‘UFRS’,‘20110101’)
    SET @iterador += 1
END

— Insere os estagiários de projeto final
WHILE @iterador <= 950
BEGIN
    INSERT INTO
Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo,Curso, Faculdade, PrevisaoTermino, TemaMonografia, LinkAcesso)
    VALUES (@iterador,‘Flávia’,‘RH’,‘Estagiário’,4,‘Serviço Social’,‘UFP’,‘20100601’,‘Teorias Sociais no Mundo Corporativo – Um caso prático’,http://ufp.br/monografias/ss/06xttss/)
    SET @iterador += 1
END

— Insere os consultores externos
WHILE @iterador <= 1000
BEGIN
    INSERT INTO
Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, Projeto, Especialidade)
    VALUES (@iterador,‘Elton’,‘Administrativo’,‘Consultor de Processos’,5,‘Mapeamento de Processos Organizacionais’,‘Estruturação de Processos’)
    SET @iterador += 1
END

— Monta uma tabela sem o recurso de sparse columns
CREATE TABLE ColaboradorNormal (
    Matricula INT NOT NULL,
    Nome VARCHAR(50) NOT NULL,
    Gerencia VARCHAR(80) NOT NULL,
    Cargo VARCHAR(50) NOT NULL,
    Tipo INT NOT NULL,
    NumeroPis CHAR(11) NULL,
    EmpresaContratante VARCHAR(80) NULL,
    DataContratacao DATE NULL,
    Curso VARCHAR(80) NULL,
    Faculdade VARCHAR(80) NULL,
    PrevisaoTermino DATE NULL,
    TemaMonografia VARCHAR(80) NULL,
    LinkAcesso VARCHAR(100) NULL,
    Projeto VARCHAR(80) NULL,
    Especialidade VARCHAR(80) NULL)

— Insere todos os registros da primeira tabela na segunda
INSERT INTO ColaboradorNormal (
    Matricula,Nome,Gerencia,Cargo,Tipo,NumeroPis,EmpresaContratante,DataContratacao,
    Curso,Faculdade,PrevisaoTermino,TemaMonografia,LinkAcesso,Projeto,Especialidade)
SELECT
    Matricula,Nome,Gerencia,Cargo,Tipo,NumeroPis,EmpresaContratante,DataContratacao,
    Curso,Faculdade,PrevisaoTermino,TemaMonografia,LinkAcesso,Projeto,Especialidade
FROM Colaborador

— Compara os tamanhos
EXEC sp_spaceused Colaborador, ‘true’
EXEC sp_spaceused ColaboradorNormal, ‘true’

O resultado mostra que as implementações são praticamente idênticas. Na verdade o uso do recurso Sparse Columns consumiu um pouco mais de espaço embora a implementação tradicional tenha desperdiçado um pouco mais conforme o quadro abaixo:

name rows reserved data index_size unused
Colaborador 1000 136 KB 96 KB 8 KB 32 KB
ColaboradorNormal 1000 136 KB 88 KB 8 KB 40 KB

Embora seja um pouco "frustante" visualizar o recurso de sparse columns não tenha incorrida na economia desejada não é difícil entender o resultado. As colunas fixas que são marcadas como sparse são apenas o Número do Pis, a data de contratação e a previsão de término. As demais colunas VARCHAR já não irão utilizar todo o espaço necessário e o uso de colunas marcadas como sparse irá incorrer nos bytes adicionais de controle o que no final das contas deixará ambas as implementações equivalentes no quesito armazenamento. A decisão ficará entre evitar o overhead de controle das colunas SPARSE ou abrir mão das possibilidades do XML na coluna "Detalhe".

A alteração da frequência pode produzir alguns resultados mais próximos dos desejados. Dessa vez, a taxa de colaboradores sofrerá algumas alterações. Haverá 10% de efetivos, 10% de terceirizados, 15% de estagiários, 10% de estagiários de projeto final e 55% de consultores externos.

— Script de distribuição de frequência
— 10% efetivos
— 10% terceirizados
— 15% estagiários
— 10% estagiários de projeto final
— 55% consultores externos
— 100% -> 1000 registros

— Exclui todos os registros de colaboradores
DELETE FROM Colaborador
DELETE FROM ColaboradorNormal

— Insere os efetivos
DECLARE @iterador INT = 1
WHILE @iterador <= 100
BEGIN
    INSERT INTO
Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, NumeroPis)
    VALUES (@iterador,‘Cristiane’,‘RH’,‘Analista Jr.’,1,‘1235324’)
    SET @iterador += 1
END

— Insere os terceirizados
WHILE @iterador <= 200
BEGIN
    INSERT INTO
Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, EmpresaContratante, DataContratacao)
    VALUES (@iterador,‘Fausto’,‘Marketing’,‘Estoquista’,2,‘B2P Associados’,‘20080219’)
    SET @iterador += 1
END

— Insere os estagiários
WHILE @iterador <= 350
BEGIN
    INSERT INTO
Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, Curso, Faculdade, PrevisaoTermino)
    VALUES (@iterador,‘Carol’,‘Finanças’,‘Estagiário’,3,‘Contabilidade’,‘UFRS’,‘20110101’)
    SET @iterador += 1
END

— Insere os estagiários de projeto final
WHILE @iterador <= 400
BEGIN
    INSERT INTO
Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo,Curso, Faculdade, PrevisaoTermino, TemaMonografia, LinkAcesso)
    VALUES (@iterador,‘Flávia’,‘RH’,‘Estagiário’,4,‘Serviço Social’,‘UFP’,‘20100601’,‘Teorias Sociais no Mundo Corporativo – Um caso prático’,http://ufp.br/monografias/ss/06xttss/
)
    SET @iterador += 1
END

— Insere os consultores externos
WHILE @iterador <= 1000
BEGIN
    INSERT INTO
Colaborador (Matricula, Nome, Gerencia, Cargo, Tipo, Projeto, Especialidade)
    VALUES (@iterador,‘Elton’,‘Administrativo’,‘Consultor de Processos’,5,‘Mapeamento de Processos Organizacionais’,‘Estruturação de Processos’)
    SET @iterador += 1
END

— Insere todos os registros da primeira tabela na segunda
INSERT INTO ColaboradorNormal (
    Matricula,Nome,Gerencia,Cargo,Tipo,NumeroPis,EmpresaContratante,DataContratacao,
    Curso,Faculdade,PrevisaoTermino,TemaMonografia,LinkAcesso,Projeto,Especialidade)
SELECT
    Matricula,Nome,Gerencia,Cargo,Tipo,NumeroPis,EmpresaContratante,DataContratacao,
    Curso,Faculdade,PrevisaoTermino,TemaMonografia,LinkAcesso,Projeto,Especialidade
FROM Colaborador

— Compara os tamanhos
EXEC sp_spaceused Colaborador, ‘true’
EXEC sp_spaceused ColaboradorNormal, ‘true’

A forte presença de consultores externos mudou significativamente a distribuição de espaço em relação às implementações:

name rows reserved data index_size unused
Colaborador 1000 200 KB 192 KB 8 KB 0 KB
ColaboradorNormal 1000 264 KB 200 KB 8 KB 56 KB

Como o consultor externo não possui os atributos de tamanho fixo como número do pis, data de contratação e previsão de término, a implementação com o uso de sparse columns se beneficia, pois, esses campos não irão ocupar espaço se não forem preenchidos o que fatalmente aconteceria na implementação tradicional.

Esse comparativo mostra que do ponto de vista de armazenamento, a distribuição dos dados exerce papel fundalmental na escolha de uma ou de outra opção.

Limitações

A adoção do recurso de Sparse Columns pode trazer várias vantagens das quais notoriamente se destaca a economia de espaço desde que obedecidos alguns pressupostos. Entretanto, essa implementação acarreta algumas limitações que devem ser conhecidas antes de se optar por esse recurso:

  • Nem todo tipo de dados é suportado (geográfico, geométrico, varbinary(max) são alguns exemplos)
  • Colunas que sejam marcadas como sparse não podem compor índices clustered e índices unique
  • Tabelas que possuam sparse columns não podem ser comprimidadas
  • A replicação do tipo MERGE não suporta Sparse Columns
  • O uso de COLUMN SET deve ser feito imediatamente sob pena da tabela ter de ser refeita
  • A coluna COLUMN SET não pode ser indexada

Há várias outras limitações a serem analisadas. O Books OnLine possua uma lista mais detalhada a partir dos links abaixo:

Using Sparse Columns
http://technet.microsoft.com/en-us/library/cc280604.aspx

Using Column Sets
http://technet.microsoft.com/en-us/library/cc280521.aspx

[ ]s,

Gustavo

2 Respostas para “A Impedância, o Mapeamento Objeto Relacional e Implementações – Parte III

  1. Primeiramente parabéns pelo artigo estou começando a estudar banco de dados e seu site é ótimo! Eu tenho uma duvida e estou pesquisando pela web minha dúvida é a seguinte se eu tenho uma tabela com 600 mil registros e uso o select para selecionar um campo digamos que demorará um certo tempo, mas digamos, se eu dividir esta tabela em duas esse tempo de pesquisa seria reduzido pela metade certo mais quais os problemas de dividir tabelas grandes em menores estou pesquisando e ninguém me dá uma resposta coerente, poderia me responder?

    • Oi Renato,

      Dividir as tabelas de fato pode auxiliar as pesquisas, mas sempre gosto de dizer que antes de pensar em dividir (ou particionar) é importante que você já tenha tentado outras coisas. Um acesso eficiente ao dado começa com uma consulta bem feita e uma estratégia de indexação eficiente. Se suas consultas são mal formuladas e você não possui índices úteis, dividir as tabelas fará muito pouco por você (no máximo irá esconder outros problemas). Agora se suas consultas já estão boas e os índices corretos estão criados e mesmo assim o throughput não está bom, então dividir pode ser algo a ser pensado, mas provavelmente isso irá acontecer com uma quantidade muito maior do que 600 mil linhas.

      Ainda quero falar sobre as vantagens e desvantagens da divisão em um Webcast futuro (o duro é conseguir dividir o tempo pra isso (rs)). Por hora eu posso dizer que dividir tabelas grandes em pedaços menores trará maiores complexidades para a aplicação, pois, você terá que avaliar qual é a tabela correta antes de fazer a pesquisa. Se usar um particionamento nativo do SGBD, você elimina essa desvantagem, mas ainda assim, o particionamento só é eficiente se você pesquisar com os critérios certos. Se você divide uma tabela em duas com base em uma data (ex: Registros2011, Registros2012, etc) a pesquisa será boa quando você pesquisa por data, mas ficará muito pior quando você pesquisar por outro critério (como assunto, CPF, etc). Nesse caso será preciso pesquisar em todas as tabelas (ou partições) separadas e isso será mais lento do que uma grande tabela.

      [ ]s,

      Gustavo

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s