RSS

Arquivo da tag: SQL Server

O mistério da FK misteriosa

Quinze anos de praia e essa eu não sabia, pode ser que vocês já sabiam, mas se não souberem, agora saberão. Pois bem, estava eu fulminando sobre o tema LINQ, que vocês já devem ter ouvido falar. Eu queria constatar a performance do trosso. Peguei uma situação típica de tabela Pai e Filho, sendo que a Filho teria um relacionamento com uma terceira tabelinha Auxiliar. Algo assim:

Eu tinha um cenário onde essa tabela Filho tinha 32mil registros, achei um bom começo para simular. Queria que me fosse listado todos os registros de Pai que tenham algum Filho que possua ligação com Auxiliar sendo essa com uma determinada descrição. Agora, poderia ter em Filho mais de uma ocorrência para o mesmo Pai que satisfizesse a condição. Por isso não poderia ser um simples JOIN entre as três tabelas (a resolução preguiçosa). Em meu cenário haviam 6 registros em Filho que satisfaziam a condição. Porém alocados em apenas 3 Pais, ou seja, o meu retorno precisaria ser 3 rows, os 3 pais. Um join entre pai e filho duplicaria esse resultado. Eu resolveria isso com a seguinte query:

SELECT Pai.*
FROM Pai
WHERE
   Pai.idPai In
   (
      SELECT Filho.idPai
      FROM Filho
         INNER JOIN Auxiliar On (Auxiliar.idAuxiliar = Filho.idAuxiliar)
      WHERE
         Auxiliar.Descricao = ‘DadoTexto’
    )

Daí, escrevi uma rotininha boba em LINQ (fiz o model dessas tabelas, o relacionamento entre elas e tudo o mais) e rodei. A execução foi satisfatória, mas eu queria saber se ele tinha resolvido a tralha com um JOIN e um DISTINCT no resultado ou se tinha usado a subquery. Abri o SQL Profile e monitorei, para a minha alegria, ele resolve assim:

SELECT
   Pai.*
FROM Pai
WHERE
   EXISTS
   (
      SELECT 1 AS [C1]
      FROM Filho
         INNER JOIN Auxiliar On Filho.idAuxiliar = Auxiliar.idAuxiliar
      WHERE
         (‘DadoTexto’ = Auxiliar.Descricao) And (Filho.idPai = Pai.idPai)
    )

Bem, agora eu precisava forçar os limites. Rodei na base insanas vezes algo assim: “INSERT INTO Filho SELECT FROM Filho”. Até que isso deixou a tabela com 5 milhões de registros. Um pouco mais de trabalho pro engine, pensei eu. Rodo as querys, tanto a do LINQ quanto a minha e o resultado vem em 19 segundos. Um pouco desapontado, mas eu percebia que ali a culpa não era do LINQ, ambas estavam levando os 19 segundos. E foi aqui que eu aprendi algo novo essa semana. Rodei um ExecutionPlan na query para ver onde estaria o maior GAP. Afinal, estava tudo com as devidas PKs e FKs e eu já tinha colocado um índice na coluna Auxiliar.Descricao. Percebo que o GAP está na relação de Auxiliar e Filho. O que não é estranho, eu enfiei 5 milhões de registros ali. Mas tem uma FK poxa. Por desencargo de consciência, resolvi criar na Filho.idAuxiliar um índice simples. E a execução das querys caiu para… INSTANTÂNEA.

E foi isso que aprendi de novo. Toda minha vida eu sempre achei que, ao se amarrar duas tabelas com uma FK a relação entre elas será beneficiada por índices. Afinal, de um lado você tem uma Primary Key e do outro uma Foreign Key. O termo Key ae, sempre me fez entender que a coluna estaria indexada. Mas não, do lado da FK, é preciso criar um índice mesmo (além da FK, claro). Quando tiver um pouco mais de tempo, vou testar isso em outros engines (pelo menos no MySQL) para saber se isso é um comportamento natural, ou se é uma característica do MS SQL Server.

 
Leave a comment

Publicado por em 18/04/2012 em SqlServer, Tecnologia

 

Tags:

SELECT TOP N: MsSQL, ORACLE e MySQL

MsSQL:

SELECT TOP 10 Codigo, Descricao
FROM Clientes

ORACLE:

SELECT Codigo, Descricao
FROM Clientes
WHERE RowNum <= 10

MySQL:

SELECT Codigo, Descricao
FROM Clientes
LIMIT 10
 
1 Comment

Publicado por em 10/09/2009 em MySQL, Oracle, SqlServer, Tecnologia

 

Tags: , ,

Surface Area Configuration no SQL Server 2008

Para onde foi o Surface Area Configuration no SQL Server 2008? Pois bem, graças a uma dica do Thiago Zavaschi, descobrimos onde foi parar essa “faceta” do SQL Server.

1. Clique com o botão direito no nome da instância (na janela do object Explorer) e selecione “Facets”.

2. Na janela “View Facets”, em Facet, selecione “Surface Area Configuration”.

3. Pronto, agora basta habilitar as features desejadas, como por exemplo a integração com o CLR.

That´s It.

 

 
1 Comment

Publicado por em 31/08/2009 em SqlServer, Tecnologia

 

Tags:

[DBNETLIB][ConnectionOpen (Connect()).]SQL Server does not exist or access denied.

Já me ocorreu algumas vezes de, ao tentar estabelecer uma conexão contra a base de dados, receber esse retorno. Eu checo e re-checo a connection string e tudo parece estar correto. No Firewall a porta 1433 está devidamente liberada. Nas configurações do SQL Server, os protocolos para a rede, habilitados. Tudo certinho.

Hoje me ocorreu um caso ainda mais inusitado. Criei duas conexões contra a mesma base SQL Server 2005. Uma usando o provedor SqlClient e a outra usando o OleDb. Mesmo usuário, mesmo senha, mesmo tudo. A que usava o SqlClient foi, a OleDb não. Fiquei cabrero.

Depois de um pouco apanhar, resolvi tentar o DNS ou IP para me referenciar ao servidor. Já que a conexão estava sendo feita para um SQL Server instalado na própria máquina, havia tomado a liberdade de usar a constante (local) como nome de servidor.

Buzz’s Eye… Na mosca… Foi só usar o DNS (ou IP) da máquina no lugar de usar a constante que o OleDb se localizou.

Buzz’s Eye

 
2 Comments

Publicado por em 08/07/2009 em ASP.NET, SqlServer, Tecnologia

 

Tags: , ,

Banco de dados SQL Server em modo de SINGLE_USER

Para colocar um banco em específico em modo de SINGLE_USER, rode o comando:

ALTER DATABASE [NOME DO BANCO DE DADOS] SET SINGLE_USER

E, para voltar ao estado normal:

ALTER DATABASE [NOME DO BANCO DE DADOS] SET MULTI_USER

Não é possível colocar os bancos MASTER, MSDB ou TEMPDB em modo de SINGLE_USER, nesses casos seria preciso iniciar o serviço do SQL Server inteiro como SINGLE_USER.

 
Leave a comment

Publicado por em 23/01/2009 em SqlServer, Tecnologia

 

Tags:

Alterar idioma (language) do SQL Server

Muitas vezes me questionam sobre como proceder com consultas envolvendo campos data. Bem, em linhas gerais podemos dizer que, fazendo a consulta utilizando o padrão ‘yyyy-mm-dd’ ou ‘yyyymmdd’ ( sendo [y]ear, [m]onth, [d]ay, respectivamente ) não teremos problemas.

SELECT
Codigo, Descricao, DataCadastro
FROM Clientes
WHERE
DataCadastro = ’2007-10-07′

Bem, não é bem assim, para que a sintaxe acima funcione, o servidor (e usuário logado) precisa estar utilizando o idioma inglês. Agora, e se o servidor tiver sido instalado com idioma em português, ou ainda, uma aplicação que antes funcionava pois estava em um servidor cujo idioma era inglês e fora restaurado num servidor cujo idioma seja português. Para esses casos precisaríamos de uma instrução para alterar o idioma, o script abaixo faria o serviço.

– EXIBIR A ATUAL CONFIGURACAO DE IDIOMA
SELECT @@language@@langid

 

– DEFINIR O IDIOMA DEFAULT PARA O SERVIDOR
EXEC sp_configure ‘default language’, 0

– DEFINIR O IDIOMA PARA CADA LOGIN DO SERVIDOR
EXEC sp_defaultlanguage ‘sa’‘us_english’
– EXEC sp_defaultlanguage ‘NomeUsuario’, ‘us_english’
– EXEC sp_defaultlanguage ‘Maquina\Usuario’, ‘us_english’

– COMANDO PARA RECONFIGURAR ALTERACOES FEITAS
RECONFIGURE

– APOS ISSO SERA PRECISO DAR UM STOP e START NO SQL SERVER

 

até a próxima.

 
Leave a comment

Publicado por em 26/12/2008 em SqlServer, Tecnologia

 

Tags:

 
Seguir

Obtenha todo post novo entregue na sua caixa de entrada.