9
votes

SQL Server prédit paresseux?

J'ai une requête: xxx

donc, le couler et la division sera-t-il effectué dans le cas où cheauplookup est 0 ? Sinon, comment puis-je éviter le calcul dans ce cas?


0 commentaires

4 Réponses :


8
votes

SQL est déclaratif: vous dites à la base de données ce que vous voulez, et non de la façon dont vous le souhaitez. La base de données est entièrement libre d'évaluer paresseusement ou avec impatience. En fait, cela peut évaluer trois fois dans l'ordre inverse pour tout ce que je sais :)

Dans de rares cas, vous pouvez améliorer les performances en rechargeant votre requête de manière à éviter une opération coûteuse spécifique. Par exemple, déplacer le point flottant mathémique vers une requête distincte forcerait l'évaluation paresseuse: xxx

dans votre exemple, je m'attendrais à ce que SQL Server choisit le meilleur moyen sans aucune indication ou astuces.


0 commentaires

2
votes

Cela dépend de la manière dont SQL Server optimise la requête, vous pouvez exécuter l'analyseur de requête à voir pour votre cas particulier

Un moyen de cheminement sûr d'optimiserait de dire P>

    WITH QueryResult AS (
    SELECT 
        someFields 
    FROM 
        someTable 
    WHERE 
        cheapLookup=1 
    )

SELECT * FROM QueryResult WHERE (CAST(someField as FLOAT)/otherField)<0.9


1 commentaires

Si vous inverserez le clauses et vérifiez le plan d'exécution, vous verrez que SQL Server est l'entier de comparer d'abord indépendamment de la déclaration avec .



3
votes

Ce que vous parlez est court-circuit, comme d'autres langues (par exemple c #).

Je crois que SQL Server peut Court-circuit mais dépend du scénario / que se passe-t-il dans l'optimiseur, donc il n'y a certainement pas une garantie que ce sera. Il suffit pourrait .

Excellente référence à ce sujet par Remus Rusanu ici:
http://rusanu.com/2009/09/13/on-sql-server-boolantan-opérator-short-circuit/


0 commentaires

16
votes

Cela dépend du plan de requête, qui est déterminé par le coût estimé de chaque plan alternatif considéré qui produirait des résultats corrects.

Si le prédicat 'cheaplookUp = 1' peut utiliser un index et il est suffisamment sélectif, SQL Server choisirait probablement de rechercher cet index et d'appliquer le deuxième prédicat en tant que résiduel (c'est-à-dire seulement l'évaluant sur des rangées que sont assortis par l'opération de recherche).

D'autre part, si châplookup n'est pas la clé de tête dans un index ou s'il n'est pas très sélectif, SQL Server peut choisir de numériser, appliquer les deux prédicats à chaque rangée rencontrée.

Le deuxième prédicat ne sera pas choisi pour une opération de recherche, à moins que la colonne calculée indexée soit calculée sur toute l'expression, et que l'utilisation de cet indice s'avère être le moyen le moins cher d'exécuter toute la requête. Si un index approprié existe, SQL Server rechercherait le résultat du deuxième prédicat <0,9 'et appliquer «CheaplookUp = 1' comme résiduel. Il est également possible que la colonne calculée indexée soit choplookup comme deuxième clé, ce qui entraînerait une recherche pure, sans résiduel.

L'autre chose à propos du deuxième prédicat est que sans colonne calculée (indexé ou non), SQL Server devra deviner la sélectivité de l'expression. Avec la colonne calculée, le serveur peut être capable de créer des statistiques sur la colonne Expression-Résultat, qui aidera l'optimiseur. Notez qu'une colonne calculée sur 'couler (unfield as flottant) / autrefield' devrait être persistée avant de pouvoir être indexée ou des statistiques créées dessus, car elles contiennent un type de données imprécis.

En résumé, ce n'est pas la complexité de l'expression qui compte tant le coût estimé de l'ensemble du plan qui utilise chacun des méthodes d'accès disponibles considérées par l'optimiseur.


0 commentaires