1

Ok, cette peut sembler une question noob, mais SQL n'est pas vraiment ma force, donc je demande de l'aide ici. J'essaie de mettre en œuvre quelque chose, mais je suis préoccupé par les problèmes de performance.La fonction Table-Valued (SQL) crée-t-elle une table pour chaque appel? [performance]

Le problème que je suis en train de corriger est quelque chose comme ceci:

J'ai une colonne avec beaucoup de données séparées par des virgules « » Quelque chose comme ceci: data1, données2, data3, data57

ce que je besoin est une boucle à travers chaque élément de données séparées par des virgules pour tous les enregistrements et puis faire quelque chose avec cette seule pièce données, est-ce que vous obtenez?

J'ai trouvé une solution qui can actually help me, mais je suis préoccupé par les performances du système, car je pourrais avoir besoin de faire plusieurs appels à cette fonction en utilisant différents paramètres!

Est-ce qu'une table est créée à chaque appel que j'ai fait à la fonction Table-Valued (UDF) ou est-ce que le serveur sql l'enregistre en cache? [peut-être aurais-je plutôt besoin d'une table temporaire?]

Nous vous remercions de votre aide à l'avance!


Note: Les données ne sont pas à moi, et je devrais l'utiliser tel quel, ce qui suggère de modifier la base de données est hors de question (mais je sais que ce serait le meilleur scénario). a Note2: Le but de cette question/problème est d'importer des données initiales dans la base de données, la performance ne peut pas être un problème sérieux car elle ne fonctionnera pas plusieurs fois, mais je veux regarder ce problème, et le faire la meilleure façon que je peux!

+1

Oui. Cette fonction va créer une entrée dans 'tempdb' et la peupler, puis en disposer à chaque appel. – TZHX

+0

Alllrighhht ... merci pour votre commentaire! S'il vous plaît écrivez une bonne réponse avec cela et je serai heureux de l'accepter :) – TiagoM

+0

Par ailleurs si vous pouvez fournir une meilleure solution pour aborder ce problème, s'il vous plaît être mon invité, je serais reconnaissant :) – TiagoM

Répondre

2

Les fonctions définies par l'utilisateur et composées de plusieurs instructions, comme celles que vous avez trouvées, créent un objet dans la base de données système tempdb, le peuplent et le suppriment lorsque l'objet est hors de portée.

Si vous souhaitez exécuter cette opération plusieurs fois avec les mêmes paramètres, vous pouvez envisager de créer une variable de table et de mettre en cache le résultat dans cette variable. Si vous allez l'appeler sur des listes différentes sur des valeurs séparées par des virgules, il n'y a pas moyen d'éviter les frais généraux. SQL Server n'est pas vraiment construit pour beaucoup de manipulation de chaînes.

Généralement, pour les travaux ponctuels, les implications de performance de cette utilisation de la tempdb ne vont pas être une préoccupation majeure pour vous. C'est plus préoccupant quand il s'agit d'un modèle commun dans la vie de la base de données au jour le jour.

Je vous suggère d'essayer, si vous le pouvez, sur un sous-ensemble de données de taille appropriée pour évaluer les performances de votre solution.

Puisque vous dites que vous êtes sur SQL Server 2016, vous pouvez utiliser la nouvelle fonction STRING_SPLIT, quelque chose comme

SELECT t.Column1, t.Column2, s.value 
FROM table t 
CROSS APPLY STRING_SPLIT(t.CsvColumn, ',') s 

mai vous permettre de vous rapprocher de l'endroit où vous voulez, sans la nécessité de définir une nouvelle fonction.Notez que votre base de données doit fonctionner sous le niveau de compatibilité 2016 (130) pour que cela soit disponible. Exécuter simplement SQL 2016 ne suffit pas (ils le font souvent avec de nouvelles fonctionnalités pour éviter le risque de rupture de compatibilité ascendante).).

+0

merci pour votre réponse, j'essaie d'exécuter cette requête pour vérifier le résultat, mais cela ne fonctionne pas jusqu'à présent, il dit "nom d'objet invalide 'STRING_SPLIT'". Aussi j'ai dû changer la valeur de erase, puisque 's' ne correspond à aucune table, peut-être que c'était une faute de frappe et vous vouliez dire t? Merci ! – TiagoM

+1

Ok, donc je voulais ajouter s comme un alias à la table retournée par STRING_SPLIT; mais on dirait que vous n'avez pas ça. Pouvez-vous vérifier le niveau de compatibilité de la base de données? Il peut être défini sur 2014 (120) ou 2012 (110), ce qui rendrait STRING_SPLIT indisponible pour vous à moins que vous ne puissiez le modifier. – TZHX

+0

Je viens de remarquer de google que j'ai besoin d'exécuter cette commande: "ALTER DATABASE TestAzureDB SET COMPATIBILITY_LEVEL = 130" – TiagoM