J'ai une requête sur une grande table qui ressemble à ceci:
declare @myIdParam int = 1
select *
from myTable
where (@myIdParam is null or myTable.Id = @myIdParam)
Il existe plusieurs conditions similaires comme celle-ci dans la clause where, et il existe également de nombreuses jointures, mais il s'agit d'un résumé.
En effet, si @myIdParam est null, nous ne voulons pas restreindre les résultats en utilisant ce paramètre.
Je ne suis pas un pro de la DB, mais d'après mes tests, il semble que cette vérification NULL soit effectuée pour chaque enregistrement et non optimisée de quelque façon que ce soit.
Si je supprime la vérification nulle et suppose que le paramètre n'est pas nul, la requête retourne instantanément. Sinon, cela prend jusqu'à dix secondes.
Existe-t-il un moyen d'optimiser cela afin que la vérification ne soit effectuée qu'une seule fois lors de l'exécution?
la source
OPTION(RECOMPILE)
Réponses:
Une façon consiste à utiliser SQL dynamique, en utilisant une vérification nulle pour ajouter éventuellement cette partie de la clause where.
la source
sp_ExecuteSQL
est manquant et que le@vc_dynamicsql
paramètre doit être aNVARCHAR
.Chaque fois que vous placez une fonction autour d'une colonne `ISNULL (@var, table.col) 'par exemple, vous supprimez la capacité de SQL à utiliser un index. C'est vraiment l'option la plus performante si vous souhaitez la conserver dans une seule requête.
Sinon, vous avez deux options. Le premier est le SQL dynamique et la réponse de @ Mystagogue est suffisante pour cela sinon vous pouvez poser deux requêtes comme celle-ci:
Dans ce format et dans le SQL dynamique, vous obtiendrez en fait un plan de requête différent pour chacune des requêtes (ce qui donnera potentiellement de meilleures performances).
la source
Bien, vous pouvez:
Gardez cependant à l'esprit que la
nullif()
fonction est essentiellement un wrappercase
. Ce n'est pas une solution miracle qui élimine par magieOR
et accélère ainsi la requête.la source
UNION
s. Quand j'ai eu cette tâche exacte, j'ai choisi le SQL dynamique.