2

Je n'ai pas été en mesure de trouver les bons mots-clés pour chercher la réponse à cette question, alors je vous prie de m'excuser si vous y avez déjà répondu.Les colonnes non sélectionnées dans les vues SQL sont-elles exécutées?

Tenir compte de la vue SQL suivante:

CREATE VIEW View1 AS 
SELECT Column1 
     ,Column2 
     ,(SELECT SUM(Column3) FROM Table2 WHERE Table2.ID = Table1.ID) -- Subquery 
FROM Table1 

Si je lance la requête suivante, sera la sous-requête est exécutée ou ne SQL Server optimisation de la requête?

SELECT Column1 FROM View1 

Je regarde cela d'un point de vue de la performance, par exemple, si la vue a fait quelques sous-requêtes (agrégations peuvent prendre beaucoup de temps si la sélection interne fait référence à une grande table). J'utilise SQL Server 2008 R2, mais je suis intéressé de savoir si la réponse diffère pour 2012 ou peut-être MySQL.

Merci.

+2

La réponse courte est que l'optimisation *** *** varie d'un fournisseur à l'autre, d'une version à l'autre. – MatBailie

Répondre

4

Comme on l'a dit, cela varie en fonction de votre SGBD (version et fournisseur), de savoir vérifier que le plan d'exécution. Cela montre pour SQL Server 2008 la sous-requête n'est pas exécuté:

enter image description here

Comme vous pouvez le voir dans le plan de dessus où Column3 n'est pas sélectionné le plan est simple sélection de table1, dans le plan inférieur que comprend Column3, la table2 est interrogée.

In SQL-Server 2008 R2 il n'est pas exécuté.

In SQL-Server 2012 il n'est pas exécuté;

In MySQL est exécuté, et les deux requêtes génèrent le même plan de:

enter image description here

Pour élaborer davantage, il dépendra aussi de votre requête exacte, ainsi que votre SGBD. Par exemple:

CREATE VIEW View2 
AS 
    SELECT t.ID, t.Column1, t.Column2, t2.Column3 
    FROM Table1 t 
      LEFT JOIN 
      ( SELECT ID, Column3 = SUM(Column3) 
       FROM Table2 
       GROUP BY ID 
      ) t2 
       ON t2.ID = t.ID 
GO 
SELECT Column1, Column2 
FROM View2; 

SELECT Column1, Column2, Column3 
FROM View2; 

enter image description here

Dans ce cas, vous obtenez des résultats similaires à la sous-requête corrélative, le plan montre seulement select de table1 si colonne3 n'est pas sélectionnée, car il est un LEFT JOIN l'optimisateur sait que la sous-requête t2 n'a aucune incidence sur le select de table1, et aucune colonne n'est utilisée, donc cela ne dérange pas. Si vous avez modifié LEFT JOIN à un INNER JOIN, par exemple,

CREATE VIEW View3 
AS 
    SELECT t.ID, t.Column1, t.Column2, t2.Column3 
    FROM Table1 t 
      INNER JOIN 
      ( SELECT ID, Column3 = SUM(Column3) 
       FROM Table2 
       GROUP BY ID 
      ) t2 
       ON t2.ID = t.ID 
GO 
SELECT Column1, Column2 
FROM View3; 

SELECT Column1, Column2, Column3 
FROM View3; 

enter image description here

Le plan de requête pour ces deux requêtes montre que parce que la colonne d'agrégat est pas utilisé dans la deuxième requête, l'optimisateur change essentiellement en vue de ceci:

SELECT t.ID, t.Column1, t.Column2 
FROM Table1 t 
     INNER JOIN 
     ( SELECT DISTINCT ID 
      FROM Table2 
     ) t2 
      ON t2.ID = t.ID; 

Comme vu par l'apparition de la Distinct Sort sur la table2 et la suppression de la Stream Aggregate.

Pour résumer, cela dépend.

+0

Grande aide! Merci beaucoup – Serital

-1

La vue est juste une définition, comme une table temporaire dans une requête. D'abord, la requête derrière la vue sera exécutée, puis votre sélection dans la vue. Alors oui, la sous-requête sera exécutée. Si vous ne le souhaitez pas, vous devez créer une nouvelle vue sans la sous-requête.

+2

Ce n'est pas toujours vrai. Certains moteurs ne vont pas *** exécuter le code de la sous-requête corrélée si la requête référençant la vue ne fait pas référence au champ contenant la sous-requête corrélée. – MatBailie

Questions connexes