Fabiano Neves's profileFabiano Neves Amorim - S...PhotosBlogListsMore ![]() | Help |
|
|
January 31 Status Backup\RestoreHoje usei um script bem legal que peguei no Blog do MVP SQL Server Junior Galvão.
Ele retorna varias informações sobre um backup ou restore que está acontecendo no banco.
SELECT command, Dateadd(ms,estimated_completion_time,Getdate()) AS Hora_Estimada_ParaTermino, estimated_completion_time / 1000 AS Segundos_Para_Termino, estimated_completion_time / 1000 / 60 Minutos_Para_Termino, start_time AS Inicio_do_Comando, percent_complete AS Percentual_Completo FROM sys.dm_exec_requests WHERE session_id = <Numero da sessão que está rodando o comando>
Thanks Junior. __________________________________________________________________ ( (55 - 14) 3404-3700 Ainda sobre TempDBAinda falando sobre o TempDB, hoje li um artigo escrito pelo Paul Randal, vale a pena gastar um tempo para ler.
Achei bem legal ele falando que mesmo quando se trata do mesmo assunto existem várias idéias e opiniões diferentes por parte dos funcionários da Microsoft. Portanto não devemos SEMPRE confiar em tudo que eles dizem ou escrevem.
Fiquei imaginando a cena, o cara querendo convencer o Paul de que o DBCC CHECKDB é isso e não é aquilo, e ele simplesmente respondendo, 'I wrote that code - I'm afraid you *are* wrong'. (Eu escrevi o código – Temo que você está errado)
Obs.: “I’m afraid” segundo o Concise Oxford Dictionary significa pedir desculpas educadamente, rs senti uma certo sarcasmo na frase.
Segue o link para o “Debate” sobre criar ou não vários arquivos para o TempDB.
http://www.sqlservercentral.com/Forums/Topic448122-361-2.aspx
__________________________________________________________________ ( (55 - 14) 3404-3700 January 29 TempDBEm relação a performance um problema muito comum é a contenção no TempDB. O Banco de dados TempDB é utilizado para várias operações, ao invés de escrever aqui quais são estas operações eu vou de CTRL-C + CTRL+V do Books Online que é mais facil. The tempdb system database is a global resource that is available to all users connected to the instance of SQL Server and is used to hold the following: · Temporary user objects that are explicitly created, such as: global or local temporary tables, temporary stored procedures, table variables, or cursors. · Internal objects that are created by the SQL Server Database Engine, for example, work tables to store intermediate results for spools or sorting. · Row versions that are generated by data modification transactions in a database that uses read-committed using row versioning isolation or snapshot isolation transactions. · Row versions that are generated by data modification transactions for features, such as: online index operations, Multiple Active Result Sets (MARS), and AFTER triggers.
No site do TechNet tem um excelente artigo falando sobre o TempDB no SQL Server 2005, segue o link Working with tempdb in SQL Server 2005.
No artigo acima podemos observar em “Troubleshooting contention caused by to DML operations” que quando temos problema de performance no TempDB é recomendado criar um arquivo de dados para cada processador existente no servidor e habilitar o trace flag 1118. Obs.: Neste caso um processador Dual Core é considerado como 2 processadores, ou seja, criar 2 arquivos.
Conforme o artigo Q328551 a mesma recomendação também foi feita pela Microsoft para servidores rodando SQL Server 2000.
No TechEd 2007 participei de uma mesa redonda sobre Otimização de Performance com o SQL Server 2005 - Dicas e Truques e discutimos sobre o TraceFlag 1118, e os profissionais da Microsoft presentes reforçaram o que os artigos acima recomendam. Lembro do Fabricio Catae Premier Field Engineer dizer o seguinte: · Por precaução e para não ter futuros problemas nós recomendamos o uso do TraceFlag 1118 e criamos um arquivo do TempDB para cada processador.
Concordo com ele, na duvida se o TempDB está sendo um problema ou não, antes de ter problema habilite o TraceFlag e crie um arquivo para cada processador do servidor.
Antes de continuar a falar sobre isso vamos entender um pouco mais sobre os Extents pois eles tem tudo a ver com o TraceFlag 1118.
No SQL Server existem dois tipos de extents, os extents mistos e extents uniformes.
Assim como o extent uniforme o extent misto tem 64 kb(8 páginas de 8k). A diferença entre eles é que um extent misto pode ter páginas de mais de um objeto diferente. Veja o exemplo abaixo.
Repare que no Extent Misto temos informações de vários objetos, Table2, Index1, Index2 e etc...
O SQL Server usa 2 tipos de controladores para alocação dos extents, o GAM e o SGAM.
· GAM - Para os extents uniformes o SQL irá usar a Global Allocation Map que é responsável por registrar as alocações dos extents uniformes de todos os objetos do banco de dados. O GAM usa um bit para controlar se o extent está livre ou alocado. Se o bit valer 1 o extent está livre se o bit valor 0 o extent está alocado.
· SGAM - Para os extents mistos o SQL irá usar a Shared Global Allocation Map como o próprio nome diz “Shared” ele é responsável por registrar quais são os extents mistos e qual deles tem páginas livres para uso. O SGAM também usa um bit para fazer este controle, se o bit for 1 então o extent é misto e tem pelo menos uma página livre para utilização, se o bit for 0 então o extent não é um extent misto ou então todas as páginas já estão utilizadas.
Vamos imaginar o seguinte cenário, um simples insert um uma nova tabela temporária. Todo objeto criado no banco de dados é iniciado com um extent misto até que a tabela ocupe 8 páginas de dados, sabendo disso então podemos dizer que o SQL irá alocar um extend misto para gravar minha informação nesta tabela temporária. Para chegar neste extent misto e na página onde minha informação será gravada o DataBase Engine usa a controladora SGAM.
Ok já sei que o SQL aloca extents mistos para novos objetos, mas o que isso tem a ver com o TraceFlag e o TempDB? Tem a ver que quando habilitamos o TraceFlag 1118 o SQL passará a não mais alocar extents mistos e sim extents uniformes, pulando a etapa que usa a SGAM para achar um extent misto.
Podemos observar que o SQL tem o trabalho de alocar extents mistos e conforme a tabela vai crescendo o SQL tem controlar se no extent atual cabe os dados que estão sendo inseridos ou se ele precisa alocar um novo extent,isso irá acontecer quando a tabela ficar maior que 64 k, para fazer este controle o SQL irá utilizar a SGAM e a PFS(controla o espaço livre dentro de uma página). Ao alocar direto um extend uniforme o SQL não precisa toda hora consultar a SGAM e a PFS para verificar se ele necessita alocar outro extent para inserir os dados.
O Luciano Moreira deu um show de explicação sobre como, quando, onde e porque utilizar o TraceFlag 1118 o artigo pode ser lido em Analisando o trace flag 1118.
Um detalhe importante é que recentemente(não tão recente assim) a Microsoft divulgou um artigo dizendo que ao fazer o que ela diz você pode ter problemas de desempenho. O artigo pode ser lido aqui Q936185,
O MVP Linchi Shea escreveu um artigo no seu blog falando sobre esse problema, Reduce the Contention on tempdb with Trace Flag 1118: To Enable, or Not to Enable?
Até a próxima e stay tuned!
______________________________________________________________ January 17 Upgrade SQL ServerAo migrar de SQL 2000 para SQL 2005 existem algumas considerações importantes no Transact-SQL que necessitam de nossa atenção, por exemplo existem alguns comandos que hoje estão rodando normalmente no SQL 2000 e ao migrar simplesmente não funcionam, vamos a alguns exemplos.
/* Exemplo de sintaxes que não funcionam ao migrar de SQL 2000 para 2005 */
use master
if exists(select * from master.dbo.sysdatabases where name = 'TesteCompatibilidade') begin drop database TesteCompatibilidade end
create database TesteCompatibilidade
use TesteCompatibilidade
if OBJECT_ID('teste') is not null begin drop table teste end GO
-- Vamos criar uma tabela para teste create table teste (id int Identity(1,1), nome VarChar(200) default NEWID()) GO
-- Vamos incluir 10 linhas na tabela teste insert into teste values(default) go 10
create index ix_teste on teste(nome) GO
-- Seta o banco para usar o nivel de compatibilidade do SQL Server 2000(80) -- Consultas que funcionam normalmente no SQL Server 2000 sp_dbcmptlevel TesteCompatibilidade, 80 GO --Consulta forcando o uso de um indice sem colocar o WITH depois do nome da tabela select * from teste(index=ix_teste) GO -- Consulta usando order by baseado em uma coluna, porem o alias ID é do mesmo nome da coluna ID -- repare que o SQL ordenou a tabela pelo campo ID da tabela e não pelo alias ID(campo nome) select ID, Nome as ID from teste order by ID GO --Consulta usando order by passando o Nome da tabela mais o alias da coluna select ID, Nome as AliasParaNome from teste order by teste.AliasParaNome GO
-- Marca o banco para usar o nivel de compatibilidade do SQL Server 2005 -- Os mesmo selects efetuados acima não funcionan no SQL Server 2005 sp_dbcmptlevel TesteCompatibilidade, 90 GO --Consulta forcando o uso de um indice sem colocar o WITH depois do nome da tabela select * from teste(index=ix_teste) GO -- Consulta usando order by baseado em uma coluna, porem o alias ID é do mesmo nome da coluna ID -- repare que o SQL ordenou a tabela pelo campo ID da tabela e não pelo alias ID(campo nome) select ID, Nome as ID from teste order by ID GO --Consulta usando order by passando o Nome da tabela mais o alias da coluna select ID, Nome as AliasParaNome from teste order by teste.AliasParaNome
A Microsoft disponibiliza um software que ajuda a evitar surpresas como estas, ele se chama “Microsoft SQL Server 2005 Upgrade Advisor” vale a pena baixar o software e rodar ele na sua base para ver as incompatibilidades. Também vale a pena dar uma lida no “SQL Server 2005 Upgrade Technical Reference Guide”.
_________________________________________________________________ ( (55 - 14) 3404-3700 January 07 Data TypesEm relação a performance uma falha muito encontrada em banco de dados SQL Server é a má escolha dos datatypes das colunas.
É muito importante conhecer e escolher corretamente os datatypes das colunas nas suas tabelas por causa dos tamanho que elas ocupam no seu banco de dados, por exemplo vamos imaginar o seguinte cenário.
create table testeA (ID BigInt Primary Key, Nome NChar(80), Data DateTime, Ano Int, Mes Int)
/* ID - BigInt = 8 bytes Nome NChar() = 160 bytes(2 bytes para cada caracter unicode) Data - DateTime = 8 bytes Ano - Int = 4 bytes Mes - Int = 4 bytes Total = 184 bytes de dados por linha. */
-- Esta mesma tabela poderia ter a seguinte estrutura
create table testeB (ID Int Primary Key, Nome Char(80), Data SmallDateTime, Ano SmallInt, Mes TinyInt)
/* ID - Int = 4 bytes Nome Char() = 80 bytes(1 bytes para cada caracter) Data - DateTime = 4 bytes Ano - SmallInt = 2 bytes Mes - TinyInt = 1 byte Total = 91 bytes de dados por linha. */
Uma página de dados do SQL Server tem uma tamanho fixo de 8k, ou 8192 bytes sendo distribuidos entre 3 partes: Page Header 96 bytes, Data Rows e Row OffSet Array.
Considerando que o SQL Server tem 8096 bytes livres(8192 - 96) para armazenamento dos dados da minha tabela e o ArrayOffSet(2 bytes) podemos dizer que dentro de cada página da minha tabela testeA temos 43 linhas de dados gravados, já na tabela testeB temos 87 registros.
Ou seja, a tabela testeB ocupa a metade do tamanho da tabela testeA, porque isso é importante? Vamos fazer alguns testes de select.
-- Primeiro vamos incluir 5000 registros em cada tabela set NoCount on declare @i Int set @i = 0 while @i < 5000 begin insert into testeA(ID, Nome, Data, Ano, Mes) values(@i, 'Fabiano - ' + Convert(VarChar, @i), GetDate(), Year(GetDate()), Month(GetDate())) insert into testeB(ID, Nome, Data, Ano, Mes) values(@i, 'Fabiano - ' + Convert(VarChar, @i), GetDate(), Year(GetDate()), Month(GetDate())) set @i = @i + 1 end
-- Repare que o SQL alocou 122 paginas para a tabela DBCC SHOWCONTIG(TesteA) --- Pages Scanned................................: 122
-- Podemos fazer a seguinte conta para verificar qual o tamanho da tabela -- 122 páginas vezes o tamanho ocupado por cada pagina / 1024 para converter o tamanho em Kb select (122 * 8192) / 1024 -- 976 -- Confirmando o tamanho da tabela sp_spaceUsed TesteA -- Data = 976
--Vamos fazer um select na tabela TesteA e verificar quantos IOs são feitos para retornar 1/5 da tabela. set statistics io on select * from testeA where ID < 1000 -- Table 'testeA'. Scan count 1, logical reads 26, physical reads 0, read-ahead reads 0.
-- Vamos verificar o mesmo select na tabela TesteB, -- Observe que o Select na tabela testeB fez bem menos leitura para retornar os dados -- obtendo assim ganho de performance. select * from testeB where ID < 1000 -- Table 'testeB'. Scan count 1, logical reads 14, physical reads 0, read-ahead reads 0.
No projeto REAL da Microsoft, a equipe de desenvolvimento opotu por definir os campos do tipo Data como Int para poder ganhar 4 bytes de diferença entre o DateTime e o Int, a data é gravada no formato ‘yyyymmdd’.
Vale lembrar tambem que no SQL Server 2005 Enterprise service pack 2 existe o campo VarDecimal que vem para substituir os campos Decimal e Numeric. Você pode ler mais sobre ele no link vardecimalStorage.docx
Fica a seguinte regra: “Quanto mais dados em menos páginas, menos leitura para retornar mais dados”. J
__________________________________________________________________ SQL Server 2008Novidades no Transact SQL do SQL Server 2008,
-- Criar uma tabela para teste create table TabNome(Nome VarChar(80), SobreNome VarChar(80))
-- Incluir 4 linhas na tabela -- Existe uma nova Sintax no SQL 2008 que permite incluir varias linhas com apenas um comando Insert. -- Commando relativo ao SQL Server 2008 insert into TabNome(Nome, Sobrenome) values('Fabiano','Amorim'),('Ricardo','Lopes'),('Eduardo','Silva'),('Maria','Oliveira') -- Commando relativo ao SQL Server 2000, 2005 insert into TabNome(Nome, Sobrenome) values('Fabiano','Amorim') insert into TabNome(Nome, Sobrenome) values('Ricardo','Lopes') insert into TabNome(Nome, Sobrenome) values('Eduardo','Silva') insert into TabNome(Nome, Sobrenome) values('Maria','Oliveira')
-- É possivel fazer um select passando uma lista como tabela segue um exemplo, -- repare que o Alias do nome das colunas é passado após o nome da tabela. select TabNome.*, Tab.Apelido from TabNome inner join ( values('Fabiano','Amo'),('Ricardo','Lop'),('Eduardo','Sil'),('Maria','Oli') ) AS tab (Nome, Apelido) ON TabNome.Nome = tab.Nome;
__________________________________________________________________ SET VS SELECTÉ muito comum durante o desenvolvimento de um código SQL necessitarmos zerar o valor das variáveis que serão utilizadas no código. Uma dica em relação a performance é que o comando SELECT é mais rápido do que o SET, porém está regra só se aplica quando podemos substituir um bloco de SET por um SELECT por ex:
-- Executa um loop zerando o valor de 10 variaveis utilizando SET -- Gere o plano de execução e repare que no plano de execução que no Loop o SQL gera um SELECT para cada comando SET. DECLARE @i Int, @Test1 int, @Start datetime DECLARE @V1 Char(6), @V2 Char(6), @V3 Char(6), @V4 Char(6), @V5 Char(6), @V6 Char(6), @V7 Char(6), @V8 Char(6), @V9 Char(6), @V10 Char(6);
SET @Test1 = 0 SET @i = 0 SET @Start = GetDate() WHILE @i < 50000 BEGIN SET @V1 = '' SET @V2 = '' SET @V3 = '' SET @V4 = '' SET @V5 = '' SET @V6 = '' SET @V7 = '' SET @V8 = '' SET @V9 = '' SET @V10 = '' SET @i = @i + 1 END SET @Test1 = DATEDIFF(ms, @Start, GetDate()) SELECT @test1
GO -- Executa um loop zerando o valor de 10 variaveis utilizando SELECT -- Diferente do primeiro plano de execução o SQL gerou apenas 1 instrução para setar os valores para as 10 variáveis. DECLARE @i Int, @Test1 int, @Start datetime DECLARE @V1 Char(6), @V2 Char(6), @V3 Char(6), @V4 Char(6), @V5 Char(6), @V6 Char(6), @V7 Char(6), @V8 Char(6), @V9 Char(6), @V10 Char(6);
SET @Test1 = 0 SET @i = 0 SET @Start = GetDate() WHILE @i < 50000 BEGIN SELECT @V1 = '', @V2 = '', @V3 = '', @V4 = '', @V5 = '', @V6 = '', @V7 = '', @V8 = '', @V9 = '', @V10 = '', @i = @i + 1; END SET @Test1 = DATEDIFF(ms, @Start, GetDate()) SELECT @test1
Fica a dica de utilizar o comando SELECT para atribuir valor a um bloco de variáveis.
Segue o link de um excelente artigo sobre o assunto. http://vyaskn.tripod.com/differences_between_set_and_select.htm
__________________________________________________________________ ( (55 - 14) 3404-3700 |
|
|