Performances de la TVF en ligne par rapport aux vues

9

J'ai une base de données où j'utilise des TVF en ligne (fonctions de valeur de table) au lieu de vues. Par exemple, je pourrais avoir deux tables appelées [modèle de voiture] et [constructeur automobile] que je joignent à l'intérieur du TVF [fnCarBrands].

Ces TVF sont ensuite appelés par d'autres TVF pour effectuer un traitement et des rapports supplémentaires. Je pourrais donc prendre ma fonction [fnCarBrands] et rejoindre la table [Purchase Year] pour former une fonction [fnCarBrandHistory]. Et ainsi de suite pour plusieurs couches de TVF.

Je pourrais probablement obtenir la même fonctionnalité en utilisant des vues, car mes TVF en ligne ne sont en réalité que des jointures de tables et d'autres TVF.

Comment les performances des TVF en ligne écrites de cette manière se comparent-elles aux vues?

FistOfFury
la source
Très probablement, vous verriez les mêmes plans d'exécution et les mêmes performances.
AK
c'est ce que je pensais, mais on m'a dit que le TVF agit comme une parenthèse en algèbre - il force le moteur de base de données à terminer cette requête avant de l'optimiser. L'utilisation de vues, me dit-on, permet à l'optimiseur d'optimiser l'ensemble de la requête en tant qu'unité.
FistOfFury
Une sorte de note secondaire, mais une idée pourquoi les TVF ont été utilisés à la place des vues? Juste une approche code-singe vs data-singe du problème?
Mark Storey-Smith
@ MarkStorey-Smith oui, la raison en est, comme vous le dites, l'approche code-singe vs data-singe.
FistOfFury

Réponses:

12

L'optimiseur de requêtes traite une fonction de valeur de table en ligne exactement comme une vue:

CREATE FUNCTION dbo.InlineUdf(@arg1 int)
RETURNS TABLE
AS
RETURN 
(
    ... your query here ...
);

Une fonction table multi-instructions est exécutée plus comme une procédure stockée. Ils doivent généralement être exécutés plusieurs fois, plutôt que d'être intégrés dans la requête principale:

CREATE FUNCTION dbo.MultiStatementUdf (@col1 int)
RETURNS @result TABLE 
(
    id int primary key NOT NULL,
    ... 
)
AS
BEGIN
   DECLARE @var1 int
   set @var1 = 42

   INSERT @result
   SELECT ...
   RETURN
END;
Andomar
la source
1
@Andomar d'après ce que je comprends, les TVF multi-déclarations sont exécutées comme une boîte noire, le moteur ne sait pas ce qu'il contient et ne peut pas optimiser la requête. Avez-vous des articles auxquels vous pouvez faire référence qui disent que les vues et les TVF en ligne sont équivalentes?
FistOfFury
4

Vous devrez créer des vues similaires aux fonctions et interroger chacune en regardant le plan d'exécution pour voir ce qui se passe avec chacune.

mrdenny
la source
Exactement. Benchmarking, voyant par vous-même - c'est le seul moyen fiable d'apprendre.
AK
@mrdenny N'y a-t-il aucun moyen de prédire comment l'optimiseur va traiter chaque type de requête? Il y a sûrement des règles à suivre.
FistOfFury
2
@FistOfFury Oui, il existe des règles, des milliers et des milliers, complétées par des centaines d'années de développement de code heuristique. C'est pourquoi vous devrez tester ou demander à Microsoft le code source de l'optimiseur.
Mark Storey-Smith
Si vous souhaitez mieux comprendre comment le moteur de base de données détermine quoi faire, vous devez lire sur SQL Server Internals, amazon.com/s/…
HLGEM
3

Bien sûr, la création de vues qui appellent d'autres vues est également une perte de performances. Ne suivez pas cette voie. Écrivez les requêtes dont vous avez besoin et n'utilisez ni TVF ni vues si vous voulez des performances. C'est la superposition qui crée le problème, c'est presque toujours une mauvaise chose à faire lors de l'interrogation d'une base de données et vous pouvez rapidement finir par atteindre la limite du nombre de tables que vous pouvez référencer aussi, d'autant plus que vous finissez souvent par référencer le mêmes tables dans différentes couches. De plus, bien que cela semble être plus facile à entretenir, ce n'est pas le cas. Essayez de déboguer ou d'ajouter une colonne en raison d'une nouvelle exigence lorsque la couche que vous devez corriger est en bas.

HLGEM
la source