Et c'est ainsi que commence le jeu malheureux "d'essayer de déjouer l'optimiseur (parce qu'il ne sait pas toujours mieux)".
Vous pouvez essayer de placer les portions de filtrage dans une sous-requête ou CTE :
SELECT TOP 30 *
FROM
(SELECT *
FROM myview, foo, bar
WHERE shared=1 AND [joins and other stuff]) t
ORDER BY sortcode;
Ce qui peut suffire à le forcer à filtrer en premier (mais l'optimiseur devient "plus intelligent" à chaque version, et peut parfois voir à travers de telles manigances). Ou vous devrez peut-être aller jusqu'à mettre ce code dans un UDF . Si vous écrivez l'UDF en tant que fonction table multi-instructions, avec le filtrage à l'intérieur, puis interrogez cette UDF avec votre TOP x
/ORDER BY
, vous avez pratiquement forcé l'ordre d'interrogation (car SQL Server est actuellement incapable d'optimiser autour des UDF multi-instructions).
Bien sûr, en y réfléchissant, l'introduction de l'UDF n'est qu'un moyen de cacher ce que nous faisons vraiment - créez une table temporaire, utilisez une requête pour la remplir (basée sur les filtres WHERE), puis une autre requête pour trouver le TOP x
de la table temporaire.