Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment améliorer les performances de la fonction non déterministe d'une colonne dans une clause ou une jointure where ?

Outre la fonction non déterministe, le problème que je vois est que vous faites des calculs sur un champ. Cela rend (généralement) tout index sur le champ inutilisable par la requête.

Le deuxième paragraphe de ce lien (Dix erreurs courantes de programmation SQL (Fonctions sur les colonnes indexées dans les prédicats) ) fournit des informations plus détaillées sur le moment où cela se produit, comment l'éviter et comment les optimiseurs peuvent parfois utiliser des index malgré l'utilisation de fonctions.

En bref, au lieu de s'appuyer sur des optimiseurs améliorés, il est souvent possible de modifier la requête en gardant le champ intact (sans effectuer de calculs dessus), mais en effectuant à la place les calculs (inversés) sur les autres valeurs. Dans votre cas, à la date actuelle fournie par GetDate() . Ensuite la requête peut utiliser l'index du champ table1.Date .

Ainsi, vous pouvez utiliser quelque chose comme :

SELECT COUNT(*) 
FROM table1
WHERE table1.Date
      BETWEEN
             /* First Day of Current Month */
          AND 
             /* Last Day of Current Month */

Et vous n'avez qu'à trouver les fonctions qui vous permettent d'obtenir le premier et le dernier jour du mois en cours.

Ce billet de blog peut vous aider :requête-du-serveur-sql-pour-trouver-le-premier-et-le-dernier-jour-du-mois-en-cours/

Encore mieux, cette question/réponse StackOverflow :moyen-le-plus-simple-de-créer-une-date-qui-est-le-premier-jour-du-mois-donné -une autre-date

Je vais devoir tester mais je pense que cette légère variation de ce qui précède fera l'affaire :

SELECT COUNT(*) 
FROM table1
WHERE table1.Date 
      >=      /* First Day of Current Month */
        DATEADD(mm, DATEDIFF(mm, 0, GetDate() ), 0) 
  AND table1.Date 
      <       /* First Day of Next Month */
        DATEADD(mm, 1 + DATEDIFF(mm, 0, GetDate() ), 0)