Sunday, 5 November 2017

Moving Average Tsql


Digamos que você tenha uma tabela com cerca de 5 milhões de registros e uma coluna nvarchar (max) preenchida com grandes dados de texto. Você deseja configurar esta coluna para NULL se SomeOtherColumn 1 da maneira mais rápida possível. A força bruta UPDATE não funciona muito bem, porque ele criará grande transação implícita e demorará para sempre. Fazer atualizações em pequenos lotes de registros de 50K ao mesmo tempo funciona, mas ainda está levando 47 horas para completar no robusto servidor 32 core64GB. Há alguma maneira de fazer esta atualização mais rápida Há alguma consulta mágica que sugira opções de tabela que sacrificam outra coisa (como a concorrência) em troca de velocidade NOTA: A criação de tabela temporária ou coluna temporária não é uma opção porque esta coluna nvarchar (max) envolve lotes De dados e, portanto, consome muito espaço PS: Sim, SomeOtherColumn já está indexado. Eu concordo, regularmente fazemos atualizações como esta em tabelas com 50 milhões ou mesmo registros de 500 milhões e acontece em segundos. Eu acho que o plano de consulta selecionado não é muito ótimo e demora muito tempo. Eu tive isso acontecer comigo quando há uma restrição de chave estrangeira em outra tabela em uma coluna não indexada. Depois de analisar o plano de consulta, percebemos que teve que escanear a outra tabela para cada exclusão que foi o culpado. Isso tinha 23 milhões de linhas, indexando a outra tabela trazendo apagamento para menos de 5 segundos. Ndash Cobusve 7 de junho 10 às 10:46 De tudo o que posso ver, não parece que seus problemas estão relacionados a índices. A chave parece estar no fato de que seu campo nvarchar (max) contém muitos dados. Pense sobre o que o SQL tem a fazer para realizar esta atualização. Como a coluna que você está atualizando é provável que mais de 8000 caracteres sejam armazenados fora da página, o que implica esforço adicional na leitura dessa coluna quando não é NULL. Quando você executa um lote de 50000 atualizações, o SQL deve colocar isso em uma transação implícita, a fim de tornar possível reverter em caso de problemas. Para reverter, ele deve armazenar o valor original da coluna no log de transações. Assumindo (por motivos de simplicidade) que cada coluna contém em média 10.000 bytes de dados, isso significa que 50.000 linhas conterão cerca de 500MB de dados, que devem ser armazenados temporariamente (no modo de recuperação simples) ou permanentemente (no modo de recuperação total). Não há como desativar os logs, pois compromete a integridade do banco de dados. Executei um teste rápido na área de trabalho lenta do meu cão, e os lotes de execução de até 10 mil tornam-se proibitivamente lentos, mas trazendo o tamanho para 1000 linhas, o que implica um tamanho de log temporário de cerca de 10 MB, funcionou muito bem. Carreguei uma tabela com 350.000 linhas e marquei 50.000 delas para atualização. Isso foi completado em cerca de 4 minutos e, uma vez que ele escala linearmente, você deve atualizar suas linhas inteiras de 5Milhões na área de trabalho lenta do meu cão em cerca de 6 horas na minha área de trabalho de 1 processador de 2GB, então eu esperaria algo muito melhor em seu servidor robusto apoiado Pela SAN ou algo assim. Você pode querer executar a sua declaração de atualização como uma seleção, selecionando apenas a chave primária e a coluna grande nvarchar, e assegure-se de que isso seja executado tão rápido quanto você espera. Claro que o gargalo pode ser outros usuários bloqueando coisas ou contenção em seu armazenamento ou memória no servidor, mas como você não mencionou outros usuários, assumirei que você tenha o DB no modo de usuário único para isso. Como uma otimização, você deve garantir que os registros de transações estejam em um grupo de disco de disco físico diferente dos dados para minimizar os tempos de busca. Isso realmente me ajudou. Fui de 2 horas a 20 minutos com isso. Na minha experiência, trabalhando no MSSQL 2005, movendo todos os dias (automaticamente) 4 milhões de registros de 46 bytes (não nvarchar (max) embora) de uma tabela em um banco de dados para outra tabela em um banco de dados diferente leva cerca de 20 minutos em um QuadCore 8GB , Servidor 2Ghz e não prejudica o desempenho da aplicação. Ao mudar eu significo INSERT INTO SELECT e depois DELETE. O uso da CPU nunca ultrapassa os 30, mesmo quando a tabela que está sendo apagada tem registros de 28M e constantemente faz cerca de 4K de inserção por minuto, mas sem atualizações. Bem, esse é meu caso, ele pode variar dependendo da carga do servidor. Especifica que as declarações (suas atualizações) podem ler linhas que foram modificadas por outras transações, mas ainda não comprometidas. No meu caso, os registros são lidos apenas. Não sei o que significa rg-tsql, mas aqui você encontrará informações sobre níveis de isolamento de transações no MSSQL. Sempre seja cuidadoso e certifique-se de compreender as implicações da leitura de transações incompatíveis. Sim, seu processo não terá que esperar para que as transações abertas se cometerão antes de excluir itens, mas é claro que se a transação não for confirmada depois de tudo isso significaria que você excluiu a linha incorretamente. Ndash Cobusve 7 de junho 10 às 10:43 Se você está executando um ambiente de produção sem espaço suficiente para duplicar todas as suas tabelas, acredito que você está procurando problemas antes ou depois. Se você fornecer alguma informação sobre o número de linhas com SomeOtherColumn1, talvez possamos pensar de outra forma, mas eu sugiro: 0) Fazer backup de sua tabela 1) Indicar a coluna da bandeira 2) Defina a opção da tabela como sem trânsito de log. Se possível 3) escreva um procedimento armazenado para executar as atualizações respondidas 2 de junho 10 às 3:17 BTW. Você precisará executar este procedimento mais de uma vez em uma vida ndash Dr. Belisarius 2 de junho 10 às 3:24 Como você define a opção da tabela para quotno log tranctionsquot ndash user356004 7 de junho 10 às 9:56 Sua resposta 2017 Stack Exchange , IncShowdown-bcp vs. DTS. A bomba de dados do SQL Server obtém dados dentro e fora de forma mais rápida. Cada gerenciador de aplicativos do SQL Server precisa mover uma grande quantidade de dados para dentro ou fora de um banco de dados do SQL Server pelo menos uma vez, então o SQL Server possui várias ferramentas para Operações de transferência de dados em massa. Neste artigo, comparo dois programas de utilidade conhecidos do SQL Server, o programa de cópias da bateria (bcp) e os Serviços de Transformação de Dados (DTS) em um cenário comum: mover dados de e para um arquivo de texto ASCII. Eu comparo o desempenho e as capacidades desses utilitários com a instrução T-SQL BULK INSERT, que, de acordo com a Microsoft, é o método de cópia em massa mais rápido (veja Arquitetura Data ImportExport no SQL Server 2000 Books Online BOL para obter mais informações). Arquitetura de cópia em massa O SQL Server possui várias APIs subjacentes. Alguns deles, a API de biblioteca de banco de dados original, OLE DB Provider para SQL Server e o driver ODBC incluem um conjunto de funções de cópia em massa. No SQL Server 6.5 e versões anteriores, o utilitário bcp usa a API da biblioteca de banco de dados. No SQL Server 7.0, a Microsoft introduziu uma nova versão do bcp que usa a API de cópia em massa ODBC em vez disso para suportar novos tipos de dados, que DB-Library não suporta. (A Microsoft estabilizou a DB-Library no seu nível atual de funcionalidade, então a empresa não vai adicionar novos recursos). Em última análise, o mecanismo de armazenamento do SQL Servers lida com chamadas de cada uma dessas APIs. Figura 1. página 38, mostra uma visão geral da arquitetura de cópia em massa do SQL Server 2000s. Dentro do mecanismo de armazenamento, a instrução T-SQL BULK INSERT, bcp e a tarefa DTS Bulk Insert executam o mesmo código. A instrução T-SQL BULK INSERT pode potencialmente ser mais rápida do que as outras porque BULK INSERT é executado completamente no processo do SQL Server. Bcp e DTS, programas de utilidade que executam em seus próprios processos, devem suportar a sobrecarga das comunicações interprocesso para passar dados do arquivo de texto de origem para o SQL Server. Quando você executa o bcp ou o DTS em um computador cliente em vez do sistema SQL Server, a necessidade de copiar os dados através de uma conexão de rede adiciona sobrecarga significativa e retarda ainda mais a operação de cópia em massa. Nos resultados do teste, a vantagem potencial da declaração T-SQL BULK INSERT nem sempre se traduz em carregamento mais rápido. De acordo com o Microsoft Product Support Services (PSS), a vantagem é significativa com tabelas muito grandes (a Microsoft rotineiramente teste com tabelas de 50 milhões de linhas), quando você carrega várias tabelas em um banco de dados em paralelo e quando você usa grupos de arquivos para segregar Diferentes volumes de disco as tabelas que você planeja carregar em paralelo. Outros fatores também influenciam o desempenho geral de uma operação de cópia em massa: os campos de ponto flutuante são mais rápidos do que os campos de caracteres e os arquivos criados para armazenar dados no formato de dados binários interno nativo do SQL Servers são mais rápidos do que os arquivos no formato de caracteres ASCII externo. Criando arquivos de teste Eu criei o banco de dados e definei todos os objetos para o meu teste usando um script T-SQL no SQL Server Query Analyzer. Então, eu fiz backup desse banco de dados vazio para criar um ponto de partida reprodutível para meus testes. Usando um gerador de dados de teste para uma tabela com linhas de 608 bytes (que consistem em uma combinação de tipos de dados varchar e inteiro), eu gere tabelas de 5000 linhas, 100.000 linhas e 1 milhão de linhas. Usei o DTS ImportExport Wizard para exportar cada tabela para arquivos de texto no formato CSV (Comma Separated Values) e no formato de campo fixo. Esses arquivos de texto se tornaram meu padrão de dados para teste DTS. Como o bcp não cria diretamente arquivos de texto no mesmo formato CSV que o DTS pode gerar (ou seja, o bcp não oferece uma maneira simples de criar automaticamente arquivos de dados de texto com campos delimitados por vírgulas e campos de texto citados), criei um segundo conjunto de arquivos de texto para Bcp e teste BULK INSERT. Eu usei o DTS para carregar os arquivos de dados do formato CSV e o bcp para exportá-los para o formato de campo de largura variável do bcps e um formato de campo fixo. Eu usei os arquivos de formato de campo de largura variável para testes bcp e BULK INSERT. O meu sistema de teste consistiu no SQL Server 2000 Enterprise Edition executado no Windows 2000 Advanced Server com o Service Pack 1 (SP1). Minha plataforma de teste foi um Compaq ProLiant 7000 com dois processadores Intel Pentium II de 500MHz e 512MB de DRAM. Meu sistema incluiu um Compaq Smart Array 3100ES Controller. Coloco os dados do SQL Server em uma matriz de RAID de 12 unidades e coloco arquivos de log em uma matriz de RAID 0 de 3 unidades separada. O DTS e sua GUI criaram cópias em massa entre o SQL Server e um arquivo de texto fácil. O assistente DTS do SQL Servers usa a tarefa Transform Data para simplificar os dados em movimento. O DTS Package Designer, que fornece recursos DTS que o assistente não expõe, permite criar procedimentos complexos. A tarefa DTS Transform Data permite modificar o formato do campo de dados durante o processo de importação ou exportação. O DTS também expõe a funcionalidade da declaração T-SQL BULK INSERT mais eficiente na tarefa DTS Bulk Insert. Utilizei o assistente DTS para a maioria dos meus testes DTS, envolvendo a tarefa de Inserção em massa apenas para verificar se o desempenho era equivalente a usar a instrução T-SQL BULK INSERT no Query Analyzer. O assistente DTS torna a exportação de uma tabela fácil de simplesmente selecionar o banco de dados e a tabela de origem, clicar em Saída do Arquivo de texto, fornecer um nome de arquivo e escolher se deseja um arquivo de saída delimitado por vírgula ou campo fixo. Importar os dados do arquivo delimitado por vírgulas foi tão fácil quanto exportar porque o formato do arquivo de texto corresponde ao formato da tabela. Quando a primeira linha no arquivo de texto contém os nomes das colunas da tabela de destino (seleção de caixa de seleção), a ordem das colunas no arquivo de texto torna-se sem importância. Sob essas condições, a importação tolerará colunas que faltam que permitem NULLs e colunas definidas com uma restrição padrão. A importação de dados de um arquivo de formato de campo fixo, que você cria usando DTS para exportar a tabela em um formato de campo fixo, foi apenas um pouco mais complexa. O DTS detecta posições de colunas que contêm dados precedidos por um espaço em branco e coloca quebras de coluna padrão nessas posições. Meus dados continham algumas dessas posições de coluna que incluíam o início de novas colunas de dados e, por padrão, definiram mais colunas de dados no arquivo de entrada do que a tabela de saída. Eu clique duas vezes nas quebras de coluna estranhas para removê-las, e a importação prosseguiu sem erro. O Assistente DST ImportExport habilita a opção Usar carga rápida por padrão. Esta opção, disponível somente quando seu sistema usa o provedor OLE DB SQL Server (SQLOLEDB), chama os provedores IRowsetFastLoad API para gerenciar de forma mais eficiente operações simples de cópia em massa. O DTS tem muitas funções que o bcp não fornece, incluindo instalações para mover dados entre bancos de dados do SQL Server, entre bancos de dados SQL Server e não-SQL Server e entre duas fontes de dados ODBC. Além disso, o DTS contém funções para modificar e transformar campos de dados durante a operação de cópia em massa. Você pode escolher entre dois modos de operação do bcp: interativos e não interativos. No modo interativo, uma série de prompts pede que você descreva o formato de arquivos de texto para o bcp. A operação bcp pode salvar essas informações em um arquivo de formato baseado em texto para uso futuro. Além disso, o bcp suporta vários formatos de arquivos padrão: arquivos de dados de caracteres ASCII padrão, arquivos de dados de caracteres Unicode, formatos de dados nativos do SQL Server e uma combinação dos dois últimos. Ao usar um desses tipos de dados padrão, o bcp não solicita informações que usa um conjunto de valores padrão e, opcionalmente, cria um arquivo de formato correspondente. Da mesma forma, quando você especifica um arquivo de formato que descreve o layout dos arquivos de dados de texto, você pode executar o bcp no modo não interativo. O arquivo de formato descreve o layout do arquivo de dados que deseja importar ou exportar e define a correspondência entre os campos do arquivo de dados e as colunas da tabela do SQL Server. O arquivo de formato oferece muito poder e flexibilidade no formato físico dos arquivos de dados e no agrupamento. (Para obter mais informações sobre o layout dos arquivos de dados, consulte a Visão geral do arquivo de formato da barra lateral, página 44.) Depois de ter um arquivo de formato de trabalho, o bcp é fácil de usar. Criei uma série de arquivos. bat simples, um para cada um dos meus testes, porque o bcp é executado como um utilitário de linha de comando. Na linha de comando, eu especificava o banco de dados e os nomes das tabelas, bem como IN ou OUT para designar a direção da cópia. Eu também forneci o nome do arquivo de formato, o nome do arquivo de dados e uma ID de usuário e senha para autenticar o acesso à tabela do SQL Server. A operação bcp possui opções que eu não usei, incluindo a capacidade de especificar dicas de cópia em massa do SQL Server. Usando T-SQL BULK INSERT A instrução BULK INSERT expõe a funcionalidade bcps em uma declaração T-SQL. BULK INSERT move dados de um arquivo para uma tabela do SQL Server. No entanto, BULK INSERT não pode exportar dados de uma tabela do SQL Server para um arquivo. A instrução T-SQL depende de um arquivo de formato estilo bcp para determinar a estrutura dos arquivos de dados. No meu teste BULK INSERT, usei os mesmos arquivos de dados e formatos que eu empregue para testar o bcp. Com essas entradas, descobri que usar a instrução BULK INSERT do Query Analyzer não era mais difícil do que usar o bcp. Então, eu criei um script T-SQL para executar a instrução BULK INSERT e calculo quanto tempo demorou para executar. T-SQL BULK INSERT suporta a maioria das mesmas opções e o arquivo de formato que o bcp faz. BULK INSERT não possui a capacidade do bcps para criar um arquivo de erro contendo as linhas que não conseguiram inserir na tabela. A instrução T-SQL não é compatível com arquivos de dados que as versões anteriores do bcp criaram esses arquivos de dados podem conter formatos de campo que o SQL Server 2000 não suporta. BULK INSERT também não possui a capacidade de usar bcps para usar formatos regionais quando copiar em massa dados de moeda, data e hora. Finalmente, BULK INSERT não possui a capacidade do bcps para configurar o tamanho do pacote de rede para operações de cópia em massa para sistemas SQL Server remotos. Resultados do teste Como o tempo que qualquer operação particular de importação ou exportação leva para completar depende tanto da configuração de hardware dos Servidores SQL, Ive escolheu representar os tempos nos gráficos de resultados do teste como uma porcentagem do tempo de importação ou exportação mais longo (isto é, teste de importação Os resultados são relativos ao período de tempo que o DTS levou para importar 1 milhão de registros preenchidos com ANSI e os resultados dos testes de exportação são relativos ao período de tempo que DTS levou para exportar 1 milhão de registros preenchidos com ANSI). Registrei o tempo relativo em que as várias operações de cópia em massa necessárias para exportar 5000, 100,000 e 1 milhão de registros Gráfico 1. página 42, mostra a comparação de exportação para 1 milhão de registros. Eu também registrei o tempo relativo que as várias operações de cópia em massa exigidas para importar 5000, 100,000 e 1 milhão de registros Gráfico 2. página 42, mostra a comparação de importações para 1 milhão de registros. (Os gráficos mostrados são representativos de todos os resultados.) Como a BOL afirma que o T-SQL BULK INSERT é o mais rápido dos métodos de cópia em massa, esperava que BULK INSERT ganhasse a corrida em meus testes. Mas bcp e BULK INSERT terminaram em um calor morto virtual e DTS não estava muito para trás. Algumas tendências dos resultados são óbvias (por exemplo, quanto mais bytes o SQL Server deve processar, mais tempo demora). O que me surpreendeu foi quanto mais tempo o SQL Server levou para importar o arquivo de dados de comprimento fixo em que cada campo varchar é preenchido com espaços em branco para o comprimento completo da coluna de 50 bytes que levou para importar o arquivo de dados de comprimento variável. Embora o número de registros, colunas e chaves que o SQL Server precisasse inserir permaneça constante, o número de bytes processados ​​correlaciona-se fortemente com o tempo necessário para o SQL Server para completar a tarefa. Por exemplo, usando o banco de dados de 1 milhão de linhas, o arquivo de dados de formato fixo DTS era 2,7 vezes o tamanho do arquivo CSV e demorou 2,5 vezes para importar. Com a média dos tempos de importação Bcp e T-SQL BULK INSERT juntas, descobri que o arquivo de dados de formato fixo era 3 vezes o tamanho do arquivo de comprimento variável e demorou 2,7 vezes para importar. Monitoramento de desempenho Depois de capturar dados de temporização para os testes de 1 milhão de linhas, executei a importação novamente com o Win2K Performance Monitor ativo, registrando a CPU e as estatísticas de utilização do disco. O Gráfico 3 mostra a utilização da CPU que eu observei e o Gráfico 4 exibe as estatísticas de IO. O perfil de utilização da CPU foi interessante. Tanto para o Bcp como para o DTS, a utilização da CPU durante a importação ocorreu em três fases distintas de duração aproximadamente igual. Durante a Fase 1, que se correlaciona grosseiramente com o tempo em que a operação de cópia em massa estava lendo o arquivo de entrada e escrevendo para tempdb, a utilização da CPU era de 44%. Durante a Fase 2, que cobre as atividades de limpeza, a utilização da CPU caiu para apenas 6%. Durante a Fase 3, que reflete o lote concluído que foi cometido de tempdb para a tabela de banco de dados de destino, a utilização da CPU foi de 46%, com uma CPU funcionando em 74% e a outra em 18%. Ao usar o T-SQL BULK INSERT, a Fase 1 ocorre no processo do SQL Server e, de acordo com minhas observações, leva apenas 82% dos ciclos de CPU que o Bcp ou DTS requer. Observe o uso intenso de uma CPU durante a Fase 3. Eu suspeito que o caso mais robusto (ou seja, quando você carrega várias tabelas simultaneamente para diferentes grupos de arquivos em diferentes dispositivos de disco) usaria vários processadores mais fortemente. Além disso, observe a redução na utilização da CPU da Fase 3 durante uma operação de INSCRIÇÃO BULK INSERTA minimamente registrada de 44% a 27% da CPU. Também observei a utilização do disco visualizando o disco lido e escrevendo IOs por segundo e o comprimento médio da fila do disco para o volume do sistema, uma matriz RAID 0 de unidade de disco e as duas matrizes RAID que hospedavam o arquivo de log de transações do SQL Server e os bancos de dados arquivo de dados. A métrica IOs por segundo mostrou uma atividade IO bastante pesada contra o volume do sistema (cerca de 90 IOs por segundo) ao longo da operação de cópia em massa, exceto por uma breve paralisação em aproximadamente a marca de três quartos. Esta matriz RAID 0 também hospedou o banco de dados tempdb e os arquivos de dados ASCII. Todos os IO nos dados do banco de dados e os arrays de log de transações ocorreram na Fase 3. Em geral, um comprimento médio da fila de IO do disco de mais do dobro do número de unidades de disco em uma matriz sinaliza um potencial gargalo (ou seja, um recurso que limita a operação de completar Mais rápido). O volume do sistema (com o banco de dados tempdb e os arquivos ASCII de entrada) teve um comprimento médio da fila de disco de 1,4 e, apesar do tráfego constante de IO, meu teste não enfatizou fortemente a fila. O meu teste também não estressou o disco com o arquivo de log de transação do banco de dados. O comprimento médio da fila do disco nunca atingiu 1. Meus testes utilizaram o volume que contém o arquivo de dados dos bancos de dados, com os comprimentos médios de espera da IO durante as operações DTS, bcp e BULK INSERT de 39.6 , 67,7 e 31,9 eventos, respectivamente, como mostra o Gráfico 4. Esses comprimentos de fila de IO indicam um gargalo de performance nesta matriz, pois possui 12 unidades. A maioria das operações de computador tem um gargalo no subsistema de IO. Ao identificar a fonte de problemas de desempenho, você saberá quais os recursos a serem atendidos se precisar acelerar a carga. Algumas surpresas Fiquei surpreso algumas vezes durante os testes (para ajudar a evitar surpresas, veja a barra lateral, algumas Gotchas para lembrar, página 39). Primeiro, importar os dados do arquivo de formato de campo fixo levou consideravelmente mais tempo do que importar os mesmos dados do arquivo de formato CSV e, após a importação, o banco de dados ocupava muito mais espaço em disco quase três vezes. Trainer espaços em branco nos campos varchar no arquivo de formato de campo fixo causou esse consumo de espaço desordenado. Você especifica os espaços em branco, configurando ANSIPADDING para ON. ON não é o padrão para o SQL Server 2000. ANSIPADDING é uma das sete opções SET que o SQL Server requer quando você trabalha com visualizações indexadas, de modo que os administradores geralmente ativam. O valor de ANSIPADDING em vigor quando você define o campo determina se trunca os espaços em branco dos campos varchar. O valor em vigor quando você adiciona ou atualiza o campo não é relevante. Executei um script no Query Analyzer para definir o banco de dados. Os bancos de dados Propriedades de Conexão são padrão para a configuração ANSIPADDING para ON, então a opção estava ativada quando eu executei o script de definição do banco de dados. Se você não estiver usando visualizações indexadas e quiser economizar espaço em disco e reduzir o tempo de processamento, defina ANSIPADDING como DESLIGADO antes de criar ou adicionar campos à sua tabela. Registro de operações de cópia em massa Minha segunda surpresa veio quando eu percebi o quão complexas as operações de cópia em massa do registro mínimo eram. Quando você importa um grande número de registros em um banco de dados, o registro completo da atualização pode preencher rapidamente o log de transações. No entanto, quando você define operações de cópia em massa para registro mínimo, o SQL Server registra apenas alocações de extensão (SQL Servers 64KB, unidades de 8 páginas de espaço em disco), e não os dados inseridos. A extensão da informação de alocação permite ao SQL Server reverter a transação, mas a quantidade de informações não é suficiente para rolar a transação para a frente durante as operações de recuperação do banco de dados. O SQL Server 7.0 forneceu a opção de banco de dados Select intobulk para suportar operações T-SQL BULK INSERT minimamente registradas. O SQL Server 2000 possui dois modelos de recuperação, simples e lotados, que podem resultar em operações BULK INSERT minimamente registradas. No entanto, essas configurações por si só não são suficientes para manter o SQL Server de iniciar completamente as operações BULK INSERT. Para obter um registro mínimo, você deve garantir que nada replica a tabela de destino, a tabela de destino não possui gatilhos, a tabela de destino está vazia ou não tem índices definidos e você usou a dica TABLOCK para que a operação BULK INSERT use tabela - Nível, em vez de nível de linha, bloqueio. Com grandes operações de cópia em massa, você também deve considerar a configuração BATCHSIZE em vigor. Por padrão, todo o arquivo de entrada é um lote que o SQL Server considera que é uma transação. Até que você cometer essa transação, o SQL Server não liberará o espaço de log de transações que contenha as informações de reversão. (Para obter mais informações sobre os modelos de recuperação, consulte Kalen Delaney, Inside SQL Server, Database Recovery Models, junho de 2000.) Usando o TABLOCK Bulk Copy Hint A dica TABLOCK é necessária para o SQL Server registrar minimamente as operações T-SQL BULK INSERT. A sugestão TABLOCK também é uma das condições necessárias ao SQL Server quando você carrega dados em uma tabela de vários clientes ao mesmo tempo, uma operação de carregamento de dados paralelo. Quando eu testei a opção TABLOCK, achei que o SQL Server usava minimamente a transação logonly 13MB em uso depois de carregar a tabela de 1 milhão de registros com a opção TABLOCK, em comparação com mais de 370MB depois de eu carregar a tabela sem a opção. No entanto, depois de carregar a tabela com a opção TABLOCK, a tabela ocupava quase 2 GB de espaço em disco. Carregando a tabela do mesmo arquivo de entrada sem a opção TABLOCK usou apenas 228 MB de espaço em disco. O comando DBCC SHOWCONTIG, que indica se seus índices estão fragmentados, mostrou as duas versões com uma densidade de varredura de 99% mais, indicando que ambas as tabelas tinham muito pouca fragmentação externa. (Para obter informações sobre vários tipos de fragmentação, consulte Kalen Delaney, Keep SQL Server Up and Running, dezembro de 2000.) A diferença entre as tabelas foi na densidade de sua página, a quantidade média de espaço usada para cada página de 8 KB atribuída à tabela. A densidade média da página da tabela com TABLOCK era apenas 11% da tabela sem a opção TABLOCK tinha uma densidade de página de 99%. Eu criei a tabela com uma restrição de chave primária em cluster na coluna IDENTITY e um FILLFACTOR de 10 por cento. O SQL Server usa o FILLFACTOR somente quando ele constrói um índice O SQL Server ignora o FILLFACTOR quando ele modifica o índice. (Para mais informações sobre FILLFACTOR, consulte Kalen Delaney, Inside SQL Server, The Fill-Factor Truth, página 29.) Assim, quando você omite a dica TABLOCK, o SQL Server parece tratar a operação T-SQL BULK INSERT como atualizações para o base de dados. Quando você especifica a sugestão TABLOCK, o SQL Server parece tratar a operação BULK INSERT como uma carga de tabela inicial. Observe que o comprimento da fila IO dos discos de dados durante as operações T-SQL BULK INSERT minimamente logadas caiu para eventos 3.7, o que especifica o número de operações de gravação seqüencial aguardando e não implica nenhum gargalo de IO de disco. Testes adicionais com o TABLOCK efetivamente revelaram que o SQL Server usou o FILLFACTOR durante o carregamento da tabela apenas ao carregar uma nova tabela. O SQL Server ignorou o FILLFACTOR quando executei BULK INSERT com TABLOCK em uma tabela vazia que anteriormente continha registros. Fontes na Microsoft explicaram esse comportamento da seguinte maneira: Em troca de desativar atualizações simultâneas com o BULK INSERT, o TABLOCK permite algumas otimizações. Imagino que você tenha um índice em cluster. Se TABLOCK estiver configurado, usamos o mesmo algoritmo internamente que usamos para preencher o índice durante a criação do índice, e é por isso que presta atenção ao fator de preenchimento. Isso resulta em tempos de carregamento mais rápidos, mas introduz algumas inconsistências no comportamento. Qual usar para carregar tabela simples quando o bcp ou T-SQL BULK INSERT irá fazer o trabalho, escolha o que melhor se adapta à maneira como você trabalha. Você não pode bater as capacidades de DTS e facilidade de uso, mas você paga uma penalidade de desempenho quando usa o Assistente de Implantação de Implantes de Servidores SQL que invoca os Dados de Transformação DTS especialmente para tabelas maiores (por exemplo, o custo foi de cerca de 15% no teste de 1 milhão de linhas). Para combinar o desempenho do T-SQL BULK INSERT com a conveniência de um pacote DTS, use a tarefa DTSs Bulk Insert. Quando você importa um grande número de linhas em um banco de dados, a forma como você projeta a operação afeta não apenas a velocidade, mas também o sucesso final das operações. O tamanho do lote determina a frequência com que o SQL Server libera espaço de registro durante a operação de cópia em massa e ajuda você a garantir que você não ficará sem espaço de log. Cumprir os requisitos para registrar minimamente a operação de cópia em massa tem um enorme impacto nos requisitos do disco de espaço de registro e algum impacto na performance, com uma pontuação de 3% mais rápida no meu teste de registro de comprimento variável de 1 milhão de linhas.

No comments:

Post a Comment