J'ai une table foo et une barre de table, où chaque foo pourrait avoir une barre (et une barre pourrait appartenir à plusieurs foos). Maintenant, j'ai besoin de sélectionner tous les foos avec une barre. Mon sql ressemble à ceciLes sous-requêtes conditionnelles sont-elles optimisées si la condition est fausse?
SELECT *
FROM foo f
WHERE [...]
AND ($param IS NULL OR (SELECT ((COUNT(*))>0)
FROM bar b
WHERE f.bar = b.id))
avec $ param étant remplacé lors de l'exécution.
La question est: La sous-requête sera-t-elle exécutée même si param est nul, ou les dbms optimiseront-ils la sous-requête?
Nous utilisons mysql, mssql et oracle. Y at-il une différence entre ceux-ci en ce qui concerne ce qui précède?
Je ne recommande pas cette approche, pour l'amour que vous serez en encapsulant trois (ou plus) syntaxe de bases de données qui va diverger. IE: MySQL supporte LIMIT, ce que ne font ni SQL Server ni Oracle - SQL Server utilise TOP alors qu'Oracle utilise ROWNUM. Utilisez une technologie d'abstraction de base de données telle que Hibernate/etc pour ne pas avoir à coder vous-même les différents SQL, ou utilisez la procédure/fonction stockée de chaque base de données pour coder et régler les requêtes pour chacun. –
Pour clarifier, mon pseudo-code 'if ... else ... end if' est censé être dans la couche application, pas en SQL. Je ne recommande pas d'ajouter de la complexité au SQL, en fait je pense que le SQL devrait être simplifié. Le point principal que je faisais est que si vous avez un simple conditionnel comme '$ param is null', vous feriez probablement mieux de le retirer du SQL et dans la couche application. Cela devrait fonctionner indépendamment du fait que OP utilise Hibernate, etc ou écrit directement SQL. –
Oui, nous utilisons une couche d'abstraction db, fabriquée à la maison, avec des requêtes nommées, qui sont écrites dans des fichiers xml et accessibles depuis notre code. Les paramètres sont transmis à partir du code et le sql est généré par la couche d'abstraction. Par conséquent, le moyen le plus simple pour l'instant est d'utiliser le type de ($ param est null || $ param == ...) comme je l'ai fait dans l'exemple. Le seul inconvénient à ce jour a été que le sql résultant est encombré avec null est null ... qui empêche le débogage un peu, mais n'a jamais été un problème de performance jusqu'à présent - jusqu'à présent, où j'ai besoin d'une jointure conditionnelle. –