Vamos dizer que você tem uma tabela com cerca de 5 milhões de registros e uma coluna nvarchar (max) preenchida com grandes dados de texto. Você deseja definir esta coluna como NULL se SomeOtherColumn 1 da maneira mais rápida possível. A força bruta UPDATE não funciona muito bem aqui, porque ele vai criar grande transação implícita e levar uma eternidade. Fazer atualizações em pequenos lotes de registros de 50K por vez funciona, mas ainda está levando 47 horas para ser concluído no servidor de 32 core64GB. Existe alguma maneira de fazer essa atualização mais rápido Há alguma mágica dicas de consulta opções de tabela que sacrifica algo mais (como simultaneidade) em troca de velocidade NOTA: Criar temp tabela ou temp coluna não é uma opção porque esta coluna nvarchar (max) envolve lotes De dados e assim consome muito espaço PS: Sim, SomeOtherColumn já está indexado. Eu concordo, nós fazemos regularmente atualizações como esta em tabelas com 50Milhões ou até 500Milhões de registros e isso acontece em segundos. Eu acho que o plano de consulta selecionado não é muito ideal e levando 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 olhar para o plano de consulta percebemos que tinha que digitalizar a outra tabela para cada apagar que foi o culpado. Isso tinha 23 milhões de linhas, indexando a outra tabela trouxe a supressão para menos de 5 segundos. Ndash Cobusve Jun 7 10 at 10:46 De tudo o que eu posso ver, não parece que seus problemas estão relacionados aos índices. A chave parece estar no fato de que seu campo nvarchar (max) contém muitos dados. Pense no que o SQL tem que fazer para executar esta atualização. Uma vez que a coluna que você está atualizando é provavelmente mais de 8000 caracteres é armazenado off-page, o que implica esforço adicional na leitura desta coluna quando não é NULL. Quando você executa um lote de 50000 atualizações SQL tem que colocar isso em uma transação implícita, a fim de tornar possível reverter para trás em caso de quaisquer problemas. Para reverter ele tem que armazenar o valor original da coluna no log de transações. Assumindo (por 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á nenhuma maneira de desativar os logs, pois isso irá comprometer a integridade do banco de dados. Eu corri um teste rápido no meu desktop cão lento, e executando lotes de até 10.000 torna-se proibitivamente lento, mas trazendo o tamanho até 1000 linhas, o que implica um tamanho de log temporário de cerca de 10MB, funcionou muito bem. Eu carregado uma tabela com 350.000 linhas e marcou 50.000 deles para atualização. Isso foi concluído em cerca de 4 minutos, e uma vez que escalas linearmente você deve ser capaz de atualizar suas fileiras inteiras 5Million em meu desktop cão lento em cerca de 6 horas no meu desktop de 1 processador 2GB, então eu esperaria algo muito melhor em seu servidor beefy apoiado Por SAN ou algo assim. Talvez você queira executar sua instrução de atualização como uma seleção, selecionando apenas a chave primária ea coluna nvarchar grande e certifique-se de que isso seja executado tão rápido quanto você espera. Claro que o gargalo pode ser outros usuários travando coisas ou contenção em seu armazenamento ou memória no servidor, mas desde que você não mencionou outros usuários eu assumirei que você tem o DB no modo de usuário único para isso. Como otimização, você deve garantir que os logs de transações estejam em um grupo de discos de disco físico diferente do que os dados para minimizar os tempos de busca. Isso realmente me ajudou. Eu fui de 2 horas a 20 minutos com isso. Na minha experiência, trabalhando em MSSQL 2005, movendo todos os dias (automaticamente) 4 milhões de 46 bytes de registros (sem 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 do aplicativo. Movendo significa INSERT INTO SELECT e depois DELETE. O uso da CPU nunca ultrapassa 30, mesmo quando a tabela sendo excluída tem 28M registros e ele faz constantemente cerca de 4K inserir por minuto, mas sem atualizações. Bem, esse é o meu caso, ele pode variar dependendo da carga do seu servidor. Especifica que as instruções (suas atualizações) podem ler linhas que foram modificadas por outras transações, mas que ainda não foram confirmadas. No meu caso, os registros são somente leitura. Eu não sei o que rg-tsql significa, mas aqui você vai encontrar informações sobre níveis de isolamento de transação em MSSQL. Tenha sempre cuidado e certifique-se de compreender as implicações da leitura transações uncomitted. Sim, o seu processo não terá de esperar por transacções abertas para confirmar antes de eliminar itens, mas é claro que se a transacção não for confirmada depois de tudo isto significaria que apagou a linha incorrectamente. Ndash Cobusve Jun 7 10 at 10:43 Se você estiver executando um ambiente de produção com espaço insuficiente para duplicar todas as suas tabelas, acredito que você está procurando por problemas mais cedo ou mais tarde. Se você fornecer algumas informações sobre o número de linhas com SomeOtherColumn1, talvez possamos pensar de outra forma, mas eu sugiro: 0) Backup sua tabela 1) Indexar a coluna flag 2) Defina a opção de tabela para nenhum log tranctions. Se possível 3) escrever um procedimento armazenado para executar as atualizações respondidas Jun 2 10 às 3:17 BTW. Você vai precisar executar este procedimento mais de uma vez em uma vida ndash Dr. belisarius Jun 2 10 at 3:24 Como você define a opção de tabela para quotno log tranctionsquot ndash User356004 Jun 7 10 às 9:56 Sua resposta 2017 Stack Exchange , IncMost pessoas estão familiarizadas com a frase, quotthis vai matar dois pássaros com um stonequot. Se você não estiver, a fase se refere a uma abordagem que aborda dois objetivos em uma ação. (Infelizmente, a expressão em si é bastante desagradável, como a maioria de nós não queremos atirar pedras em animais inocentes) Hoje I39m vai cobrir algumas noções básicas sobre dois grandes recursos no SQL Server: o índice Columnstore (disponível somente no SQL Server Enterprise) e O SQL Query Store. A Microsoft implementou o índice Columnstore no SQL 2012 Enterprise, embora o tenha aprimorado nas últimas duas versões do SQL Server. A Microsoft lançou o Query Store no SQL Server 2016. Então, quais são esses recursos e por que eles são importantes? Bem, eu tenho uma demo que apresentará os dois recursos e mostrar como eles podem nos ajudar. Antes de eu ir mais longe, eu também cobrir este (e outros recursos SQL 2016) no meu artigo revista CODE sobre novos recursos SQL 2016. Como uma introdução básica, o índice Columnstore pode ajudar a acelerar as consultas que scanaggregate sobre grandes quantidades de dados e O Query Store controla as execuções de consultas, os planos de execução e as estatísticas de tempo de execução que você normalmente precisa coletar manualmente. Confie em mim quando eu digo, estas são grandes características. Para esta demonstração, usarei o banco de dados de demonstração Microsoft Contoso Retail Data Warehouse. Falando francamente, Contoso DW é como quota realmente grande AdventureWorksquot, com tabelas contendo milhões de linhas. (A maior tabela AdventureWorks contém aproximadamente 100.000 linhas no máximo). Você pode baixar o banco de dados Contoso DW aqui: microsoften-usdownloaddetails. aspxid18279. Contoso DW funciona muito bem quando você quer testar o desempenho em consultas contra tabelas maiores. O Contoso DW contém uma tabela de fatos de data warehouse padrão chamada FactOnLineSales, com 12,6 milhões de linhas. Isso certamente não é a maior tabela de data warehouse do mundo, mas também não é uma criança. Suponha que eu quero resumir o montante das vendas de produtos para 2009 e classificar os produtos. Eu poderia consultar a tabela de fatos e juntar-se à tabela de dimensão do produto e usar uma função RANK, assim: Aqui há um conjunto de resultados parciais das 10 linhas superiores, por Vendas totais. No meu laptop (i7, 16 GB de RAM), a consulta leva em qualquer lugar 3-4 segundos para ser executado. Isso pode não parecer o fim do mundo, mas alguns usuários podem esperar resultados quase instantâneos (da maneira que você pode ver resultados quase instantâneos ao usar o Excel contra um cubo OLAP). O único índice que eu tenho atualmente nesta tabela é um índice agrupado em uma chave de vendas. Se eu olhar para o plano de execução, o SQL Server faz uma sugestão para adicionar um índice de cobertura para a tabela: Agora, apenas porque o SQL Server sugere um índice, doesn39t significa que você deve cegamente criar índices em cada quotmissing indexquot mensagem. No entanto, nesta instância, o SQL Server detecta que estamos a filtrar com base no ano e utilizando a chave de produto eo montante de vendas. Assim, o SQL Server sugere um índice de cobertura, com o DateKey como o campo de chave de índice. A razão pela qual chamamos isso de índice de quotcoveringquot é porque o SQL Server irá quotbring ao longo dos campos não-chave que usamos na consulta, quotfor o ridequot. Dessa forma, o SQL Server não precisa usar a tabela ou o índice em cluster em todo o mecanismo de banco de dados pode simplesmente usar o índice de cobertura para a consulta. Os índices de cobertura são populares em determinados cenários de armazenamento de dados e de banco de dados de relatórios, embora tenham um custo de manutenção do mecanismo de banco de dados. Nota: Os índices de cobertura têm sido em torno de um longo tempo, por isso eu haven39t ainda cobriu o índice Columnstore eo Query Store. Então, vou adicionar o índice de cobertura: Se eu re-execute a mesma consulta que eu corri há um momento (aquela que agregou o valor de vendas para cada produto), a consulta às vezes parece correr cerca de um segundo mais rápido, e eu recebo um Plano de execução diferente, que usa um Index Seek em vez de um Index Scan (usando a chave de data no índice de cobertura para recuperar as vendas para 2009). Assim, antes do índice Columnstore, esta poderia ser uma forma de optimizar esta consulta em versões mais antigas do SQL Server. Ele é executado um pouco mais rápido do que o primeiro, e eu recebo um plano de execução com um Index Seek em vez de um Index Scan. No entanto, existem alguns problemas: Os dois operadores de execução quotIndex Seekquot e quotHash Match (Aggregate) quot ambos essencialmente operam quotrow por rowquot. Imagine isso em uma tabela com centenas de milhões de linhas. Relacionado, pense sobre o conteúdo de uma tabela de fatos: neste caso, um único valor de chave de data e um único valor de chave de produto podem ser repetidos em centenas de milhares de linhas (lembre-se, a tabela de fatos também tem chaves para geografia, promoção, vendedor , Etc.) Assim, quando o quotIndex Seekquot e o quotHash Matchquot trabalham linha por linha, eles estão fazendo isso sobre valores que podem ser repetidos em muitas outras linhas. Isso é normalmente onde I39d segue para o SQL Server Columnstore índice, que oferece um cenário para melhorar o desempenho desta consulta de maneiras surpreendentes. Mas antes de eu fazer isso, vamos voltar no tempo. Vamos voltar ao ano de 2010, quando a Microsoft introduziu um add-in para o Excel conhecido como PowerPivot. Muitas pessoas provavelmente se lembram de ver demonstrações do PowerPivot para Excel, onde um usuário poderia ler milhões de linhas de uma fonte de dados externa para o Excel. O PowerPivot comprimiria os dados e forneceria um mecanismo para criar tabelas dinâmicas e gráficos dinâmicos que funcionassem a velocidades incríveis em relação aos dados compactados. O PowerPivot usou uma tecnologia em memória que a Microsoft denominou quotVertiPaqquot. Essa tecnologia em memória do PowerPivot basicamente levaria valores de chave de negócios duplicados e os comprimia para um único vetor. A tecnologia em memória também digitalizaria esses valores em paralelo, em blocos de várias centenas de cada vez. A linha de fundo é que a Microsoft assou uma grande quantidade de aprimoramentos de desempenho no recurso VertiPaq em memória para usarmos, logo depois da caixa proverbial. Porque estou fazendo exame deste passeio pequeno para baixo a pista da memória Porque no SQL Server 2012, Microsoft executou um dos recursos os mais importantes no history de seu motor do banco de dados: o índice do Columnstore. O índice é realmente um índice somente no nome: é uma maneira de tomar uma tabela do SQL Server e criar um columnstore compactado na memória que comprime valores de chave estrangeira duplicados para valores de vetor simples. A Microsoft também criou um novo pool de buffer para ler esses valores vetoriais compactados em paralelo, criando o potencial para ganhos de desempenho enormes. Assim, I39m vai criar um índice columnstore na tabela, e I39ll ver quanto melhor (e mais eficientemente) a consulta é executada, versus a consulta que é executado contra o índice de cobertura. Então, eu criarei uma cópia duplicada de FactOnlineSales (I39ll chamá-lo de FactOnlineSalesDetailNCCS), e I39ll criará um índice columnstore na tabela duplicada dessa maneira eu won39t interferir com a tabela original eo índice de cobertura de qualquer maneira. Em seguida, I39ll criar um índice columnstore na nova tabela: Observe várias coisas: I39ve especificado várias colunas de chave estrangeira, bem como o montante de vendas. Lembre-se de que um índice columnstore não é como um índice tradicional de armazenamento em fila. Não há quotkeyquot. Estamos simplesmente indicando quais colunas SQL Server deve compactar e colocar em um columnstore in-memory. Para usar a analogia do PowerPivot para Excel quando criamos um índice columnstore, estamos dizendo ao SQL Server que faça essencialmente a mesma coisa que o PowerPivot fez quando importamos 20 milhões de linhas para o Excel usando o PowerPivot. Então, I39ll re-executa a consulta, desta vez usando A tabela duplicada FactOnlineSalesDetailNCCS que contém o índice columnstore. Esta consulta é executada instantaneamente em menos de um segundo. E eu também posso dizer que mesmo que a mesa tivesse centenas de milhões de linhas, ela ainda funcionaria com o proverbial quotbat de um cílio. Podemos olhar para o plano de execução (e em alguns momentos, vamos), mas agora é hora de cobrir o recurso Query Store. Imagine por um momento que executamos ambas as consultas durante a noite: a consulta que usou a tabela regular de FactOnlineSales (com o índice de cobertura) e, em seguida, a consulta que usou a tabela duplicada com o índice Columnstore. Quando iniciamos a sessão na manhã seguinte, gostaríamos de ver o plano de execução para ambas as consultas à medida que elas ocorreram, assim como as estatísticas de execução. Em outras palavras, gostaríamos de ver as mesmas estatísticas que seríamos capazes de ver se executamos ambas as consultas interativamente no SQL Management Studio, transformadas em TIME e IO Statistics e visualizamos o plano de execução logo após a execução da consulta. Bem, isso é o que o Query Store nos permite fazer, podemos ativar (habilitar) o Query Store para um banco de dados, que acionará o SQL Server para armazenar a execução da consulta e planejar as estatísticas para que possamos visualizá-las mais tarde. Então, I39m vai habilitar o Query Store no banco de dados Contoso com o seguinte comando (e I39ll também limpar qualquer cache): Então I39ll executar as duas consultas (e quotpretendquot que eu os corri há horas): Agora vamos fingir que correram horas atrás. De acordo com o que eu disse, o Query Store irá capturar as estatísticas de execução. Então, como posso vê-los Felizmente, isso é muito fácil. Se eu expandir o banco de dados Contoso DW, ver uma pasta Query Store. O Query Store tem uma enorme funcionalidade e I39ll tentar cobrir grande parte dela em postagens de blog subseqüentes. Mas para agora, eu quero ver as estatísticas de execução sobre as duas consultas e examinar especificamente os operadores de execução para o índice columnstore. Então, clique com o botão direito do mouse no Top Resource Consuming Queries e execute essa opção. Isso me dá um gráfico como o abaixo, onde eu posso ver o tempo de duração da execução (em milissegundos) para todas as consultas que foram executadas. Nesse caso, a Consulta 1 era a consulta contra a tabela original com o índice de cobertura e a Consulta 2 estava contra a tabela com o índice columnstore. Os números não são o índice columnstore superou o índice tablecovering original por um fator de quase 7 para 1. Eu posso mudar a métrica para olhar para o consumo de memória em vez disso. Nesse caso, observe que a consulta 2 (a consulta de índice columnstore) usou muito mais memória. Isso demonstra claramente por que o índice columnstore representa a tecnologia quotin-memoryquot O SQL Server carrega todo o índice columnstore na memória e usa um pool de buffer completamente diferente com operadores de execução aprimorados para processar o índice. OK, então temos alguns gráficos para ver as estatísticas de execução podemos ver o plano de execução (e operadores de execução) associados a cada execução Sim, nós podemos Se você clicar na barra vertical para a consulta que usou o índice columnstore, você verá a execução Abaixo. A primeira coisa que vemos é que o SQL Server executou uma varredura de índice columnstore, e que representou quase 100 do custo da consulta. Você pôde dizer, quotWait um minuto, a primeira consulta usou um índice de coberta e executou um índice procura assim que como pode uma varredura do índice do columnstore ser mais rápida que uma pergunta legitimate, e felizmente there39s uma resposta. Mesmo quando a primeira consulta executou um index seek, ela ainda executou quotrow por rowquot. Se eu colocar o mouse sobre o operador de varredura de índice columnstore, eu vejo uma dica de ferramenta (como a abaixo), com uma configuração importante: o Modo de Execução é BATCH (em oposição a ROW.), Que é o que tínhamos com a primeira consulta usando o Índice de cobertura). Esse modo BATCH informa-nos que o SQL Server está processando os vetores compactados (para quaisquer valores de chave externa duplicados, como a chave do produto e a chave de data) em lotes de quase 1.000, em paralelo. Assim, o SQL Server ainda é capaz de processar o índice columnstore muito mais eficientemente. Além disso, se eu colocar o mouse sobre a tarefa Hash Match (Aggregate), também vejo que o SQL Server está agregando o índice columnstore usando o modo Batch (embora o próprio operador represente um percentual minúsculo do custo da consulta) SQL Server comprime os valores nos dados, trata os valores como vetores, e lê-los em blocos de quase mil valores em paralelo, mas a minha consulta só queria dados para 2009. Assim é o SQL Server digitalização sobre o Conjunto de dados Uma vez mais, uma boa pergunta. A resposta é, quotNot reallyquot. Felizmente para nós, o novo pool de buffer de índice columnstore executa outra função chamada quotsegment eliminationquot. Basicamente, o SQL Server examinará os valores de vetor para a coluna de chave de data no índice columnstore e eliminará os segmentos que estão fora do escopo do ano 2009. I39ll parar aqui. Em postagens subseqüentes, o I39ll cobre o índice columnstore eo Query Store com mais detalhes. Essencialmente, o que vimos aqui hoje é que o índice Columnstore pode acelerar significativamente as consultas que scanaggregate sobre grandes quantidades de dados eo Query Store irá capturar execuções de consulta e nos permitir examinar as estatísticas de execução e desempenho mais tarde. No final, gostaríamos de produzir um conjunto de resultados que mostre o seguinte. Observe três coisas: As colunas essencialmente pivô todas as Razões de retorno possíveis, depois de mostrar o valor de vendas O conjunto de resultados contém um total de subtotais pela semana (domingo) data em todos os clientes (onde o cliente é NULL) Linha (onde o cliente ea data são ambos NULL) Primeiro, antes de eu entrar no final do SQL que poderia usar o dynamic dynamicmatrix capacidade no SSRS. Simplesmente precisaríamos combinar os dois conjuntos de resultados por uma coluna e então poderíamos alimentar os resultados para o controle de matriz SSRS, que irá espalhar as razões de retorno através do eixo colunas do relatório. No entanto, nem todos usam SSRS (embora a maioria das pessoas deve). Mas mesmo assim, às vezes os desenvolvedores precisam consumir conjuntos de resultados em algo que não seja uma ferramenta de geração de relatórios. Assim, para este exemplo, vamos assumir que queremos gerar o conjunto de resultados para uma página de grade da web e, possivelmente, o desenvolvedor quer quotstrip outquot as linhas subtotal (onde eu tenho um ResultSetNum valor de 2 e 3) e colocá-los em uma grade de resumo. Então, linha de fundo, precisamos gerar a saída acima diretamente de um procedimento armazenado. E como uma torção adicionada na próxima semana poderia haver Return Reason X e Y e Z. Então nós don39t saber quantas razões de retorno poderia haver. Nós simples queremos que a consulta pivote sobre os possíveis valores distintos para a razão de retorno. Aqui é onde o T-SQL PIVOT tem uma restrição que precisamos para fornecer-lhe os valores possíveis. Como não sabemos que até o tempo de execução, precisamos gerar a seqüência de consulta dinamicamente usando o padrão SQL dinâmico. O padrão SQL dinâmico envolve gerar a sintaxe, peça por peça, armazená-lo em uma seqüência de caracteres e, em seguida, executar a seqüência de caracteres no final. SQL dinâmico pode ser complicado, pois temos de incorporar sintaxe dentro de uma seqüência de caracteres. Mas, neste caso, é nossa única opção verdadeira se quisermos lidar com um número variável de razões de retorno. Sempre achei que a melhor maneira de criar uma solução SQL dinâmica é descobrir o quotidealquot gerado-consulta seria no final (neste caso, dadas as razões de retorno que sabemos sobre) e, em seguida, engenharia reversa-lo por piecing Juntos uma parte de cada vez. E assim, aqui está o SQL que precisamos se soubéssemos que as razões de retorno (de A a D) eram estáticas e não mudariam. A consulta faz o seguinte: Combina os dados de SalesData com os dados de ReturnData, onde nós quothard-wirequot a palavra Sales como um tipo de ação forma a tabela de vendas e, em seguida, use a razão de retorno dos dados de retorno na mesma coluna ActionType. Isso nos dará uma coluna de ActionType limpa na qual girar. Estamos combinando as duas instruções SELECT em uma expressão de tabela comum (CTE), que é basicamente uma subconsulta de tabela derivada que usamos posteriormente na próxima instrução (para PIVOT) Uma declaração PIVOT contra o CTE, que somar os dólares para o Action Type Estar em um dos possíveis valores do Tipo de Ação. Observe que este não é o conjunto de resultados final. Estamos colocando isso em um CTE que lê a partir do primeiro CTE. A razão para isso é porque nós queremos fazer vários agrupamentos no final. A instrução SELECT final, que lê a partir do PIVOTCTE e combina-lo com uma consulta subseqüente contra o mesmo PIVOTCTE, mas onde também implementar dois agrupamentos no recurso GROUPING SETS em SQL 2008: GROUPING pela data de fim de semana (dbo. WeekEndingDate) GRUPO para todas as linhas () Então, se soubéssemos com certeza que nunca teríamos mais códigos de razão de retorno, então essa seria a solução. No entanto, precisamos considerar outros códigos de razão. Portanto, precisamos gerar essa consulta inteira acima como uma grande seqüência onde construímos as possíveis razões de retorno como uma lista separada por vírgulas. I39m vai mostrar todo o código T-SQL para gerar (e executar) a consulta desejada. E então eu dividi-lo em partes e explicar cada passo. Então primeiro, aqui está o código inteiro para gerar dinamicamente o que eu tenho acima. Existem basicamente cinco etapas que precisamos cobrir. Passo 1 . Nós sabemos que em algum lugar na mistura, precisamos gerar uma seqüência de caracteres para isso na consulta: SalesAmount, razão A, razão B, razão C, razão D0160016001600160 O que podemos fazer é construído uma expressão de tabela comum temporária que combina o hard wired quotSales Coluna de quantidade com a lista exclusiva de possíveis códigos de razão. Uma vez que temos que em um CTE, podemos usar o pequeno truque de FOR XML PATH (3939) para recolher essas linhas em uma única seqüência de caracteres, coloque uma vírgula em frente de cada linha que a consulta lê e, em seguida, use STUFF para substituir A primeira instância de uma vírgula com um espaço vazio. Este é um truque que você pode encontrar em centenas de blogs SQL. Então, esta primeira parte constrói uma string chamada ActionString que podemos usar mais abaixo. Passo 2 . Também sabemos que we39ll quer somar as colunas de razão geradas geradas, juntamente com a coluna de vendas padrão. Portanto, precisamos de uma string separada para isso, que eu chamo SUMSTRING. I39ll simplesmente usar o ActionString original e, em seguida, substituir os colchetes externos com sintaxe SUM, mais os suportes originais. Passo 3: Agora começa o verdadeiro trabalho. Usando essa consulta original como um modelo, queremos gerar a consulta original (começando com o UNION das duas tabelas), mas substituindo quaisquer referências a colunas articuladas com as strings geradas dinamicamente acima. Além disso, embora não seja absolutamente necessário, também criei uma variável para simplesmente qualquer combinação de feed de retorno de carro que desejamos incorporar na consulta gerada (para legibilidade). Então we39ll construir toda a consulta em uma variável chamada SQLPivotQuery. Passo 4. Continuamos construindo a consulta novamente, concatenando a sintaxe que podemos quothard-wire com o ActionSelectString (que geramos dinamicamente para manter todos os possíveis valores de razão de retorno) Passo 5. Finalmente, we39ll gera a parte final da Pivot Query, que lê a partir da 2ª expressão de tabela comum (PIVOTCTE, a partir do modelo acima) e gera o SELECT final para ler a partir do PIVOTCTE e combiná-lo com uma 2ª leitura contra PIVOTCTE para Implementar os conjuntos de agrupamento. Finalmente, nós podemos quotexecutequot a seqüência usando o sistema SQL armazenado proc spexecuteSQL Então espero que você pode ver que o processo para seguir para este tipo de esforço é Determine qual seria a consulta final, com base em seu conjunto atual de dados e valores Um modelo de consulta) Escreva o código T-SQL necessário para gerar esse modelo de consulta como uma string. Posivelmente, a parte mais importante é determinar o conjunto único de valores em que você PIVOT e, em seguida, colapso-los em uma Cadeia de caracteres usando a função STUFF eo truque FOR XML PATH (3939) Então, o que está na minha mente hoje Bem, pelo menos 13 itens Dois Eu escrevi um projecto de BDR que se concentrou (em parte) sobre o papel da educação e do valor de um bom fundo de artes liberais não apenas para a indústria de software, mas mesmo para outras indústrias também. Um dos temas deste particular BDR enfatizou um ponto de vista fundamental e esclarecido do renomado arquiteto de software Allen Holub sobre as artes liberais. Parafraseando fielmente a sua mensagem: destacou os paralelos entre a programação e o estudo da história, lembrando a todos que a história é leitura e escrita (e acrescentam, identificando padrões), eo desenvolvimento de software também é leitura e escrita (e, novamente, identificação de padrões ). E assim eu escrevi um pedaço de opinião que focalizou isto e outros tópicos relacionados. Mas até hoje, eu nunca cheguei perto de publicá-lo. De vez em quando eu penso em revisá-lo, e eu até me sento por alguns minutos e faço alguns ajustes. Mas então a vida em geral iria ficar no caminho e Id nunca terminá-lo. Então o que mudou Algumas semanas atrás, o colunista CoDe Magazine e o líder da indústria Ted Neward escreveram um artigo em sua coluna regular, Managed Coder, que chamou minha atenção. O título do artigo é On Liberal Arts. E eu recomendo que todos lê-lo. Ted discute o valor de um fundo de artes liberais, a falsa dicotomia entre um fundo de artes liberais e sucesso no desenvolvimento de software, ea necessidade de escrever bem. Ele fala sobre alguns de seus próprios encontros anteriores com o gerenciamento de pessoal de RH em relação a sua formação educacional. Ele também enfatiza a necessidade de aceitar e se adaptar às mudanças em nosso setor, bem como as características de um profissional de software bem-sucedido (ser confiável, planejar com antecedência e aprender a superar o conflito inicial com outros membros da equipe). Portanto, é uma ótima leitura, como são Teds outros CoDe artigos e entradas de blog. Também me fez voltar a pensar sobre minhas opiniões sobre este (e outros tópicos) também, e finalmente me motivou a terminar meu próprio editorial. Então, melhor tarde do que nunca, aqui estão os meus atuais Bakers Dúzia de Reflexões: Eu tenho um ditado: A água congela em 32 graus. Se você está em um papel de formação, você pode pensar que você está fazendo tudo no mundo para ajudar alguém quando na verdade, theyre apenas sentindo uma temperatura de 34 graus e, portanto, as coisas arent solidificação para eles. Às vezes leva apenas um pouco mais de esforço ou outro catalizador ideachemical ou uma nova perspectiva que significa que aqueles com educação prévia pode recorrer a diferentes fontes. A água congela a 32 graus. Algumas pessoas podem manter altos níveis de concentração, mesmo com um quarto cheio de pessoas barulhentas. Eu não sou um deles ocasionalmente eu preciso de alguma privacidade para pensar através de uma questão crítica. Algumas pessoas descrevem isso como você tem que aprender a andar longe dele. Dito de outra forma, é uma busca pelo ar rarefeito. Na semana passada eu passei horas em um quarto semi-iluminado e quieto com um quadro branco, até que compreendi um problema completamente. Foi só então que eu poderia ir falar com outros desenvolvedores sobre uma solução. A mensagem aqui não é para pregar como você deve ir sobre o seu negócio de resolver problemas, mas sim para todos saberem os seus pontos fortes eo que funciona, e usá-los para sua vantagem, tanto quanto possível. Algumas frases são como unhas no quadro-negro para mim. Use-o como um momento de ensino é um. (Por que é como unhas em um quadro-negro Porque se você estiver em um papel de mentor, você normalmente deve estar no modo de momento de ensino de qualquer maneira, no entanto sutilmente). Heres outro eu não posso realmente explicar isto nas palavras, mas eu compreendo-o. Isso pode soar um pouco frio, mas se uma pessoa verdadeiramente não pode explicar alguma coisa em palavras, talvez eles não entendem. Claro, uma pessoa pode ter uma sensação fuzzy de como funciona algo Eu posso blefar meu caminho através de descrever como funciona uma câmera digital, mas a verdade é que eu realmente não entendo tudo isso bem. Existe um campo de estudo conhecido como epistemologia (o estudo do conhecimento). Uma das bases fundamentais para entender se é uma câmera ou um padrão de design - é a capacidade de estabelecer contexto, identificar a cadeia de eventos relacionados, os atributos de quaisquer componentes ao longo do caminho, etc Sim, a compreensão é por vezes muito trabalho árduo , Mas mergulhar em um tópico e quebrá-lo aparte vale a pena o esforço. Mesmo aqueles que evitam a certificação reconhecerá que o processo de estudar para os testes de certificação ajudará a preencher lacunas no conhecimento. Um gerente de banco de dados é mais provável contratar um desenvolvedor de banco de dados que pode falar extemporaneamente (e sem esforço) sobre níveis de isolamento de transação e acionadores, em oposição a alguém que tipo de sabe sobre ele, mas luta para descrever o seu uso. Há outro corolário aqui. Ted Neward recomenda que os desenvolvedores ocupam falar em público, blogs, etc Concordo 100. O processo de falar em público e blogs vai praticamente obrigá-lo a começar a pensar sobre os temas e quebrar as definições que você pode ter tomado por certo. Alguns anos atrás, eu pensei que eu entendia a declaração T-SQL MERGE muito bem. Mas só depois de escrever sobre isso, falando, colocando questões de outros que tinham perspectivas que nunca me ocorreu que o meu nível de compreensão aumentou exponencialmente. Eu conheço uma história de um gerente de contratação que uma vez entrevistou um autor de desenvolvedor para uma posição contratual. O gerente de contratação foi desdenhoso das publicações em geral, e latiu ao candidato, Então, se você está indo para o trabalho aqui, você prefere escrever livros ou escrever código Sim, doente conceder que em qualquer indústria haverá alguns acadêmicos pura. Mas o que o gerente de contratação perdeu foi as oportunidades para reforçar e afiar conjuntos de habilidades. Enquanto limpava uma velha caixa de livros, me deparei com um tesouro dos anos 80: Programmers at Work. Que contém entrevistas com um muito jovem Bill Gates, Ray Ozzie, e outros nomes bem conhecidos. Cada entrevista e cada insight vale o preço do livro. Na minha opinião, a entrevista mais interessante foi com Butler Lampson. Que deu alguns conselhos poderosos. Para o inferno com a informática. É absolutamente ridículo. Estudar matematica. Aprenda a pensar. Ler. Escreva. These things are of more enduring value. Learn how to prove theorems: A lot of evidence has accumulated over the centuries that suggests this skill is transferable to many other things. Butler speaks the truth . Ill add to that point learn how to play devils advocate against yourself. The more you can reality-check your own processes and work, the better off youll be. The great computer scientistauthor Allen Holub made the connection between software development and the liberal arts specifically, the subject of history. Here was his point: what is history Reading and writing. What is software development Among other things, reading and writing . I used to give my students T-SQL essay questions as practice tests. One student joked that I acted more like a law professor. Well, just like Coach Donny Haskins said in the movie Glory Road, my way is hard. I firmly believe in a strong intellectual foundation for any profession. Just like applications can benefit from frameworks, individuals and their thought processes can benefit from human frameworks as well. Thats the fundamental basis of scholarship. There is a story that back in the 1970s, IBM expanded their recruiting efforts in the major universities by focusing on the best and brightest of liberal arts graduates. Even then they recognized that the best readers and writers might someday become strong programmersystems analysts. (Feel free to use that story to any HR-type who insists that a candidate must have a computer science degree) And speaking of history: if for no other reason, its important to remember the history of product releases if Im doing work at a client site thats still using SQL Server 2008 or even (gasp) SQL Server 2005, I have to remember what features were implemented in the versions over time. Ever have a favorite doctor whom you liked because heshe explained things in plain English, gave you the straight truth, and earned your trust to operate on you Those are mad skills . and are the result of experience and HARD WORK that take years and even decades to cultivate. There are no guarantees of job success focus on the facts, take a few calculated risks when youre sure you can see your way to the finish line, let the chips fall where they may, and never lose sight of being just like that doctor who earned your trust. Even though some days I fall short, I try to treat my client and their data as a doctor would treat patients. Even though a doctor makes more money There are many clichs I detest but heres one I dont hate: There is no such thing as a bad question. As a former instructor, one thing that drew my ire was hearing someone criticize another person for asking a supposedly, stupid question. A question indicates a person acknowledges they have some gap in knowledge theyre looking to fill. Yes, some questions are better worded than others, and some questions require additional framing before they can be answered. But the journey from forming a question to an answer is likely to generate an active mental process in others. There are all GOOD things. Many good and fruitful discussions originate with a stupid question. I work across the board in SSIS, SSAS, SSRS, MDX, PPS, SharePoint, Power BI, DAX all the tools in the Microsoft BI stack. I still write some code from time to time. But guess what I still spend so much time doing writing T-SQL code to profile data as part of the discovery process. All application developers should have good T-SQL chops. Ted Neward writes (correctly) about the need to adapt to technology changes. Ill add to that the need to adapt to clientemployer changes. Companies change business rules. Companies acquire other companies (or become the target of an acquisition). Companies make mistakes in communicating business requirements and specifications. Yes, we can sometimes play a role in helping to manage those changes and sometimes were the fly, not the windshield. These sometimes cause great pain for everyone, especially the I. T. people. This is why the term fact of life exists we have to deal with it. Just like no developer writes bug-free code every time, no I. T. person deals well with change every single time. One of the biggest struggles Ive had in my 28 years in this industry is showing patience and restraint when changes are flying from many different directions. Here is where my prior suggestion about searching for the rarified air can help. If you can manage to assimilate changes into your thought process, and without feeling overwhelmed, odds are youll be a significant asset. In the last 15 months Ive had to deal with a huge amount of professional change. Its been very difficult at times, but Ive resolved that change will be the norm and Ive tried to tweak my own habits as best I can to cope with frequent (and uncertain) change. Its hard, very hard. But as coach Jimmy Duggan said in the movie A League of Their Own: Of course its hard. If it wasnt hard, everyone would do it. The hard, is what makes it great . A powerful message. Theres been talk in the industry over the last few years about conduct at professional conferences (and conduct in the industry as a whole). Many respected writers have written very good editorials on the topic. Heres my input, for what its worth. Its a message to those individuals who have chosen to behave badly: Dude, it shouldnt be that hard to behave like an adult. A few years ago, CoDe Magazine Chief Editor Rod Paddock made some great points in an editorial about Codes of Conduct at conferences. Its definitely unfortunate to have to remind people of what they should expect out of themselves. But the problems go deeper. A few years ago I sat on a five-person panel (3 women, 2 men) at a community event on Women in Technology. The other male stated that men succeed in this industry because the Y chromosome gives men an advantage in areas of performance. The individual who made these remarks is a highly respected technology expert, and not some bozo making dongle remarks at a conference or sponsoring a programming contest where first prize is a date with a bikini model. Our world is becoming increasingly polarized (just watch the news for five minutes), sadly with emotion often winning over reason. Even in our industry, recently I heard someone in a position of responsibility bash software tool XYZ based on a ridiculous premise and then give false praise to a competing tool. So many opinions, so many arguments, but heres the key: before taking a stand, do your homework and get the facts . Sometimes both sides are partly rightor wrong. Theres only one way to determine: get the facts. As Robert Heinlein wrote, Facts are your single clue get the facts Of course, once you get the facts, the next step is to express them in a meaningful and even compelling way. Theres nothing wrong with using some emotion in an intellectual debate but it IS wrong to replace an intellectual debate with emotion and false agenda. A while back I faced resistance to SQL Server Analysis Services from someone who claimed the tool couldnt do feature XYZ. The specifics of XYZ dont matter here. I spent about two hours that evening working up a demo to cogently demonstrate the original claim was false. In that example, it worked. I cant swear it will always work, but to me thats the only way. Im old enough to remember life at a teen in the 1970s. Back then, when a person lost hisher job, (often) it was because the person just wasnt cutting the mustard. Fast-forward to today: a sad fact of life is that even talented people are now losing their jobs because of the changing economic conditions. Theres never a full-proof method for immunity, but now more than ever its critical to provide a high level of what I call the Three Vs (value, versatility, and velocity) for your employerclients. I might not always like working weekends or very late at night to do the proverbial work of two people but then I remember there are folks out there who would give anything to be working at 1 AM at night to feed their families and pay their bills. Always be yourselfyour BEST self. Some people need inspiration from time to time. Heres mine: the great sports movie, Glory Road. If youve never watched it, and even if youre not a sports fan I can almost guarantee youll be moved like never before. And Ill close with this. If you need some major motivation, Ill refer to a story from 2006. Jason McElwain, a high school student with autism, came off the bench to score twenty points in a high school basketball game in Rochester New York. Heres a great YouTube video. His mother said it all . This is the first moment Jason has ever succeeded and is proud of himself. I look at autism as the Berlin Wall. He cracked it. To anyone who wanted to attend my session at todays SQL Saturday event in DC I apologize that the session had to be cancelled. I hate to make excuses, but a combination of getting back late from Detroit (client trip), a car thats dead (blown head gasket), and some sudden health issues with my wife have made it impossible for me to attend. Back in August, I did the same session (ColumnStore Index) for PASS as a webinar. You can go to this link to access the video (itll be streamed, as all PASS videos are streamed) The link does require that you fill out your name and email address, but thats it. And then you can watch the video. Feel free to contact me if you have questions, at kgoffkevinsgoff November 15, 2013 Getting started with Windows Azure and creating SQL Databases in the cloud can be a bit daunting, especially if youve never tried out any of Microsofts cloud offerings. Fortunately, Ive created a webcast to help people get started. This is an absolute beginners guide to creating SQL Databases under Windows Azure. It assumes zero prior knowledge of Azure. You can go to the BDBI Webcasts of this website and check out my webcast (dated 11102013). Or you can just download the webcast videos right here: here is part 1 and here is part 2. You can also download the slide deck here. November 03, 2013 Topic this week: SQL Server Snapshot Isolation Levels, added in SQL Server 2005. To this day, there are still many SQL developers, many good SQL developers who either arent aware of this feature, or havent had time to look at it. Hopefully this information will help. Companion webcast will be uploaded in the next day look for it in the BDBI Webcasts section of this blog. October 26, 2013 Im going to start a weekly post of T-SQL tips, covering many different versions of SQL Server over the years Heres a challenge many developers face. Ill whittle it down to a very simple example, but one where the pattern applies to many situations. Suppose you have a stored procedure that receives a single vendor ID and updates the freight for all orders with that vendor id. create procedure dbo. UpdateVendorOrders update Purchasing. PurchaseOrderHeader set Freight Freight 1 where VendorID VendorID Now, suppose we need to run this for a set of vendor IDs. Today we might run it for three vendors, tomorrow for five vendors, the next day for 100 vendors. We want to pass in the vendor IDs. If youve worked with SQL Server, you can probably guess where Im going with this. The big question is how do we pass a variable number of Vendor IDs Or, stated more generally, how do we pass an array, or a table of keys, to a procedure Something along the lines of exec dbo. UpdateVendorOrders SomeListOfVendors Over the years, developers have come up with different methods: Going all the way back to SQL Server 2000, developers might create a comma-separated list of vendor keys, and pass the CSV list as a varchar to the procedure. The procedure would shred the CSV varchar variable into a table variable and then join the PurchaseOrderHeader table to that table variable (to update the Freight for just those vendors in the table). I wrote about this in CoDe Magazine back in early 2005 (code-magazinearticleprint. aspxquickid0503071ampprintmodetrue. Tip 3) In SQL Server 2005, you could actually create an XML string of the vendor IDs, pass the XML string to the procedure, and then use XQUERY to shred the XML as a table variable. I also wrote about this in CoDe Magazine back in 2007 (code-magazinearticleprint. aspxquickid0703041ampprintmodetrue. Tip 12)Also, some developers will populate a temp table ahead of time, and then reference the temp table inside the procedure. All of these certainly work, and developers have had to use these techniques before because for years there was NO WAY to directly pass a table to a SQL Server stored procedure. Until SQL Server 2008 when Microsoft implemented the table type. This FINALLY allowed developers to pass an actual table of rows to a stored procedure. Now, it does require a few steps. We cant just pass any old table to a procedure. It has to be a pre-defined type (a template). So lets suppose we always want to pass a set of integer keys to different procedures. One day it might be a list of vendor keys. Next day it might be a list of customer keys. So we can create a generic table type of keys, one that can be instantiated for customer keys, vendor keys, etc. CREATE TYPE IntKeysTT AS TABLE ( IntKey int NOT NULL ) So Ive created a Table Typecalled IntKeysTT . Its defined to have one column an IntKey. Nowsuppose I want to load it with Vendors who have a Credit Rating of 1..and then take that list of Vendor keys and pass it to a procedure: DECLARE VendorList IntKeysTT INSERT INTO VendorList SELECT BusinessEntityID from Purchasing. Vendor WHERE CreditRating 1 So, I now have a table type variable not just any table variable, but a table type variable (that I populated the same way I would populate a normal table variable). Its in server memory (unless it needs to spill to tempDB) and is therefore private to the connectionprocess. OK, can I pass it to the stored procedure now Well, not yet we need to modify the procedure to receive a table type. Heres the code: create procedure dbo. UpdateVendorOrdersFromTT IntKeysTT IntKeysTT READONLY update Purchasing. PurchaseOrderHeader set Freight Freight 1 FROM Purchasing. PurchaseOrderHeader JOIN IntKeysTT TempVendorList ON PurchaseOrderHeader. VendorID Te mpVendorList. IntKey Notice how the procedure receives the IntKeysTT table type as a Table Type (again, not just a regular table, but a table type). It also receives it as a READONLY parameter. You CANNOT modify the contents of this table type inside the procedure. Usually you wont want to you simply want to read from it. Well, now you can reference the table type as a parameter and then utilize it in the JOIN statement, as you would any other table variable. Então, você tem. A bit of work to set up the table type, but in my view, definitely worth it. Additionally, if you pass values from , youre in luck. You can pass an ADO data table (with the same tablename property as the name of the Table Type) to the procedure. For developers who have had to pass CSV lists, XML strings, etc. to a procedure in the past, this is a huge benefit. Finally I want to talk about another approach people have used over the years. SQL Server Cursors. At the risk of sounding dogmatic, I strongly advise against Cursors, unless there is just no other way. Cursors are expensive operations in the server, For instance, someone might use a cursor approach and implement the solution this way: DECLARE VendorID int DECLARE dbcursor CURSOR FASTFORWARD FOR SELECT BusinessEntityID from Purchasing. Vendor where CreditRating 1 FETCH NEXT FROM dbcursor INTO VendorID WHILE FETCHSTATUS 0 EXEC dbo. UpdateVendorOrders VendorID FETCH NEXT FROM dbcursor INTO VendorID The best thing Ill say about this is that it works. And yes, getting something to work is a milestone. But getting something to work and getting something to work acceptably are two different things. Even if this process only takes 5-10 seconds to run, in those 5-10 seconds the cursor utilizes SQL Server resources quite heavily. Thats not a good idea in a large production environment. Additionally, the more the of rows in the cursor to fetch and the more the number of executions of the procedure, the slower it will be. When I ran both processes (the cursor approach and then the table type approach) against a small sampling of vendors (5 vendors), the processing times where 260 ms and 60 ms, respectively. So the table type approach was roughly 4 times faster. But then when I ran the 2 scenarios against a much larger of vendors (84 vendors), the different was staggering 6701 ms versus 207 ms, respectively. So the table type approach was roughly 32 times faster. Again, the CURSOR approach is definitely the least attractive approach. Even in SQL Server 2005, it would have been better to create a CSV list or an XML string (providing the number of keys could be stored in a scalar variable). But now that there is a Table Type feature in SQL Server 2008, you can achieve the objective with a feature thats more closely modeled to the way developers are thinking specifically, how do we pass a table to a procedure Now we have an answer Hope you find this feature help. Feel free to post a comment. Importing SQL Server Data Using SSIS - Which Option is Fastest By: Daniel Calbimonte Read Comments (27) Related Tips: More Integration Services Development This article is useful for SSIS developers who do not know which tasks are best to use in an SSIS projects. The main problem is that at the end of development if performance is slow then you will need to rebuild the project and change components. This article shows various ways of importing data and shows which types of components perform best within SSIS. The contest will be between the following components: ODBC Tasks ADO NET Tasks OLEDB Task SQL Server Destination T-SQL Tasks I created different SSIS packages in order to test performance. In this demo I used SSIS 2012 and the database Adventureworks 2012 . In this demo I am going to import the table AdventureWorks2012.Sales. SalesOrderDetail to the test2 database which is on the same instance of SQL Server. SalesOrderDetails is the table with more rows in AdventureWorks2012. In order to create the database test2 and the destination table dbo. OrderDetails, use this T-SQL code: Test 1 - ODBC Tasks The first example will use ODBC Source and ODBC Destination as shown below: When we run the package we notice the average time is 5 minutes 57 seconds to import the rows: Test 2 - ADO NET Tasks As noticed, ODBC is pretty slow. Lets try another approach. We are going to truncate the destination table first: Lets try ADO tasks to import the same data and verify if these components are faster: The average elapsed time in my testing was 11 seconds. This is much better. Test 3 - OLEDB Tasks This time we are going to import the same data using the OLEDB Tasks. Again we will truncate the table in the test2 database first. The average elapsed time is 5 seconds. Note that I am using the fast load option with the Table Lock option in the OLE DB Destination Task: If we do not use the fast load option, the average elapsed time was 2 minutes and 21 seconds: OK. The fast load option really improves performance. I will return to that configuration. What about the OLE DB Source. By default I am using the option Table or view in the OLE DB Source as shown below: Lets use a SQL Command instead as shown below. The average elapsed time is 2.85 seconds . Test 4 - SQL Server Destination Now, lets try to use the SQL Destination as the destination instead of OLE DB Destination: The average elapsed time is 2.5 seconds. At this point it is the best option. Test 5 - Execute T-SQL Task Finally, some people think that the best option is to use the Execute T-SQL Task: I am using a simple insert statement to import data from one source to another: The average elapsed time is 1.8 seconds Finally Ive been told that if the query runs inside a stored procedure it is even faster: Lets create a stored procedure: After creating the stored procedure we are going to call it in the Execute T-SQL Task: The average elapsed time is 2.12 seconds . The stored procedures does not improve performance. Lets review the table with the results: You may think the morale of the story is to use the Execute T-SQL Task instead of other SSIS tasks. In this example we were importing data on the same instance, but this will not always be the case. So the morale of the story is that there are many alternatives when creating a SSIS project and we have to carefully study the alternatives in different scenarios. There are great SSIS tools and we do not always use the best options. With each new version of SSIS new tasks are added and performance may be improved with existing tasks. The main changes in SSIS for SQL 2008 and 2012 are related to performance improvements. Next Steps If you are working in a SSIS project make sure you are using the best tasks and also verify if there are other SSIS tasks that can be used in your project. Also make sure you are following the best practices recommended by the experts: Last Update: 7132012 Great read and analysis, but I have one caveat to add. If you need to move a large amount of data, you need to take care of the transaction log growth. This is not a much of a concern using SSIS. For instance, I needed to move 1.3 billion rows (15 columns) and began using TSQL which quickly filled my logs. However, using OLE DB Source and Destination (Bulk Inserts) with fast load, there was little impact to the log file. Thursday, September 20, 2012 - 9:19:12 AM - vinodhkumar Its very useful. great job. Thanks Monday, August 27, 2012 - 10:54:42 AM - Orlando Colamatteo I agree with some others that the testbed is a bit contrived. If youre looking to move data from one table to another on the same instance then SSIS will rarely be a viable option. Some form of T-SQL will almost certainly outperform an SSIS operation. A more realistic scenario is moving data between two disparate data sources. It is surpising how poorly the ODBC Destination performs, especially in light of what Microsoft has publicly said in that they will be moving away from OLE DB interfaces and standardizing on ODBC in future products: In the ODBC Destination I expected Microsoft to implement the loading of data via the bulk load API as they did with the FastLoad option of the OLE DB Destination. On a separate note regarding loading data into MySQL with SSIS: In the past I did some performance tests with the Cherry City OLE DB driver for MySQL and it is horribly slow as it only inserts one row at a time. This is not to mention the fact that it crashed BIDS regularly when developing with it. Given the lack of a benefit I would stick with the tools built into SSIS and avoid the hassle of installing and configuring a third party driver. If youre using SSIS 2005 I would recommend using a Script Component as a Destination and issuing batch-inserts against a connection made using the MySQL ODBC Driver: msdn. microsoften-uslibraryms135939.aspx If youre using SSIS 2008 I would recommend using an ADO NET Destination with the MySQL ODBC Driver. In my tests it was only able to achieve about 240 rowsminute throughput to MySQL which is quite disappointing: msdn. microsoften-uslibrarybb895291(vsql.105).aspx If youre using SSIS 2012 I would recommend using an ODBC Destination with the MySQL ODBC Driver. In my tests it outperformed the ADO NET Destination over 3 to 1 but still only achieved about 800 rowsminute throughput, which was still quite disappointing: msdn. microsoften-uslibraryhh758691(vsql.110).aspx
No comments:
Post a Comment