Ajude com melhorias em STRING_SPLIT

Ajude com melhorias em STRING_SPLIT

Ajude com melhorias em STRING_SPLIT 1
cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br


Ajude com melhorias em STRING_SPLIT 2 Estamos no meio do ciclo entre lançamentos, onde ainda não estamos ouvindo sobre nenhum dos recursos planejados para o SQL Server vNext. Este é provavelmente o melhor momento para pressionar a Microsoft por melhorias, desde que possamos apoiar nossos pedidos com casos de negócios legítimos. No SQL Server 2016, STRING_SPLIT resolveu uma lacuna que faltava há muito tempo em um idioma que, reconhecidamente, não era destinado ao processamento complicado de cadeias. E é isso que eu quero trazer hoje.

Por anos antes do SQL Server 2016 (e desde então), escrevemos nossas próprias versões, as aprimoramos ao longo do tempo e até discutimos sobre quem era mais rápido. Nós escrevemos sobre cada microssegundo que conseguimos ganhar e eu, por exemplo, afirmei várias vezes: “este é meu último post sobre como dividir strings!” No entanto, aqui estamos nós.

Eu sempre argumentarei que os parâmetros com valor de tabela são a maneira correta de separar as strings. Mas enquanto Eu Como esses blobs de vírgula separados por vírgula nunca devem ser expostos ao banco de dados dessa forma, a divisão de strings continua sendo um caso de uso predominante – algumas das postagens do meu blog estão entre as 5 principais visualizações todo dia.

Então, por que as pessoas ainda estão tentando dividir strings com funções com valor de tabela quando existe uma substituição superior? Alguns, tenho certeza, porque ainda estão em versões mais antigas, presos em um nível de compatibilidade mais antigo ou não conseguem se separar de forma alguma porque os TVPs não são suportados pelo idioma ou pelo ORM. Quanto ao resto, enquanto STRING_SPLIT é conveniente e eficiente, não é perfeito. Possui restrições que sofrem algum atrito e tornam a substituição de chamadas de função existentes por uma chamada nativa complicada ou impossível.

Aqui está a minha lista.

Essas limitações não são exaustivas, mas listei as importantes em meu ordem de prioridade (e Andy Mallon também publicou um blog sobre isso hoje):

  • Delimitador de um caractere
    Parece que a função foi criada com apenas o caso de uso simples: CSV. As pessoas têm seqüências mais complexas do que 1,2,3 ou A|B|Ce geralmente são alimentados em seus bancos de dados a partir de sistemas fora de seu controle. Como descrevo nesta resposta e nesta dica, existem maneiras de contornar isso (operações de substituição realmente ineficientes), mas são realmente feias e, francamente, desfazem todos os benefícios de desempenho oferecidos pela implementação nativa. Além disso, parte do atrito com esse se refere especificamente a: “Bem, o PostgreSQL string_to_array lida com vários delimitadores de caracteres; então, por que o SQL Server não pode? ”

    Implementação: aumente o tamanho máximo de separator.

  • Nenhuma indicação de ordem de entrada
    A saída da função é um conjunto e, inerentemente, os conjuntos não têm ordem. E enquanto na maioria dos casos você verá uma string de entrada como bob,ted,frank sair nessa ordem (bob ted frank), não há garantia (com ou sem desleixo) (ORDER BY (SELECT NULL)) hackear). Muitas funções domésticas incluem uma coluna de saída para indicar a posição ordinal na sequência, o que pode ser importante se a lista estiver organizada em uma ordem definida ou se a posição ordinal exata tiver algum significado.

    Implementação: adicione um opção para incluir a coluna de posição ordinal na saída.

    cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br
  • O tipo de saída é baseado apenas na entrada
    A coluna de saída da função é fixada em varchar ou nvarchar, e é determinado com precisão pelo comprimento de toda a cadeia de entrada, não pelo comprimento do elemento mais longo. Então, você tem uma lista de 25 letras, o tipo de saída é finalmente varchar(51). Para cadeias mais longas, isso pode resultar em problemas com concessões de memória, dependendo do uso, e pode apresentar problemas se o consumidor confiar em outro tipo de dados que está sendo produzido (por exemplo, int, que às vezes especifica funções para evitar conversões implícitas posteriormente). Como solução alternativa, os usuários às vezes criam suas próprias tabelas temporárias ou variáveis ​​de tabela e despejam a saída da função antes de interagir com ela, o que pode levar a problemas de desempenho.

    Implementação: adicione uma opção para especificar o tipo de saída de value.

  • Não é possível ignorar elementos vazios ou delimitadores à direita
    Quando você tem uma string como a,,,b,, você pode esperar que apenas dois elementos sejam gerados, pois os outros três estão vazios. A maioria dos TVFs personalizados que eu vi cortam delimitadores à direita e / ou filtram cadeias de comprimento zero, mas STRING_SPLIT retorna todas as 5 linhas. Isso dificulta a troca na função nativa porque você também precisa adicionar uma lógica de agrupamento para eliminar essas entidades.

    Implementação: adicione uma opção para ignorar elementos vazios.

  • Não é possível filtrar duplicatas
    Essa é provavelmente uma solicitação menos comum e fácil de resolver usando DISTINCT ou GROUP BY, mas muitas funções fazem isso automaticamente para você. Não há diferença real no desempenho nesses casos, mas existe algo que você se esquece de adicionar (pense em uma lista grande, com muitas duplicatas, juntando-se a uma tabela grande).

    Implementação: adicione uma opção para filtrar duplicatas.

Aqui está o caso de negócios.

Tudo isso parece teórico, mas aqui está o caso comercial, que posso garantir que é muito real. Na Wayfair, temos uma propriedade substancial do SQL Server e temos literalmente dezenas de equipes diferentes que criaram suas próprias funções com valor de tabela ao longo dos anos. Alguns são melhores que outros, mas todos são chamados de milhares e milhares de linhas de código. Recentemente, iniciamos um projeto em que estamos tentando substituí-los por chamadas para STRING_SPLIT, mas nos deparamos com casos de bloqueio envolvendo várias das limitações acima.

Alguns são fáceis de contornar, usando uma função de wrapper. Mas o delimitador de caractere único limitação nos forçou a avaliar a solução alternativa terrível usando REPLACE, e isso provou eliminar o benefício de desempenho que esperávamos, fazendo-nos acelerar. E, nesses casos, perdemos um chip de negociação importante ao pressionar por atualizações para o nível de compatibilidade (nem todos os bancos de dados estão em 130, não importa 140). Nesses casos, estamos perdendo não apenas STRING_SPLIT melhorias, mas também em outras 130 + melhorias de desempenho que estaríamos desfrutando se STRING_SPLIT foi convincente o suficiente por si só para promover a atualização do nível compat.

Então, estou pedindo sua ajuda.

Visite este item de feedback:

Vote! Mais importante, Deixe um comentário descrevendo casos de uso reais que você faz STRING_SPLIT uma dor ou um não iniciante para você. Apenas os votos não são suficientes, mas, com feedback tangível e qualitativo, há uma chance de que eles comecem a levar a sério essas lacunas.

Sinto vontade de apoiar delimitadores com vários caracteres (até, digamos, expandindo de [n]varchar(1) para [n]varchar(5)) é uma melhoria não intrusiva que desbloqueia muitas pessoas que compartilham meu cenário. Outros aprimoramentos podem ser mais difíceis de implementar, alguns exigindo sobrecargas e / ou aprimoramentos de idioma; portanto, não espero todas essas correções no vNext. Mas mesmo uma pequena melhoria reiteraria que STRING_SPLIT foi um investimento que valeu a pena e que não será abandonado (como, por exemplo, bancos de dados contidos, um dos recursos mais famosos de drive-by).

Obrigado pela atenção!