Je pose la question car tant de questions que je vois en SQL se résument à: "C'est lent. Comment puis-je l'accélérer"? Ou sont des didacticiels indiquant "Faites de cette façon et non de cette façon car c'est plus rapide".
Il me semble qu'une grande partie de SQL sait exactement comment une expression serait exécutée et à partir de cette connaissance, elle choisit des styles d'expression qui fonctionnent mieux. Cela ne cadre pas avec un aspect de la programmation déclarative - celui de quitter le système pour décider de la meilleure façon d'effectuer le calcul avec vous en spécifiant simplement ce que le calcul doit produire.
Un moteur SQL ne devrait-il pas se soucier de savoir si vous l'avez utilisé in
, exists
ou join
s'il est vraiment déclaratif, ne devrait-il pas simplement vous donner la bonne réponse dans un délai raisonnable si possible par l'une des trois méthodes? Ce dernier exemple est provoqué par ce post récent qui est du type mentionné dans mon paragraphe d'ouverture.
Index
Je suppose que l'exemple le plus simple que j'aurais pu utiliser concerne la création d'un index pour une table. Le gumph ici sur w3schools.com essaie même de l'expliquer comme quelque chose d'invisible par l'utilisateur qui est là pour des raisons de performances. Leur description semble mettre les indices SQL dans le camp non déclaratif et ils sont régulièrement ajoutés à la main pour des raisons purement de performance.
Est-il vrai que leur est quelque part une base de données SQL idéale qui est beaucoup plus déclarative que tous les autres, mais parce que c'est bon, on n'en entend pas parler?
la source
select whatever from sometable where FKValue in (select FKValue from sometable_2 where other_value = :param)
. Il devrait être trivial de voir comment reformuler cela avec unexists
ou unjoin
.Réponses:
SQL est théoriquement déclaratif. Mais vous savez ce qu'ils disent de la différence entre la théorie et la pratique ...
À la base, le concept de "programmation déclarative" n'a jamais été vraiment efficace, et ne le sera probablement jamais tant que nous n'aurons pas un compilateur basé sur l'IA capable de regarder le code et de répondre à la question "quelle est l'intention de ce code?" intelligemment, de la même manière que la personne qui l'a écrit. Au cœur de chaque langage déclaratif se trouve tout un tas de codes impératifs essayant frénétiquement de résoudre ce problème sans l'aide d'une IA.
Souvent, cela fonctionne étonnamment bien, car les cas les plus courants sont des cas courants , que les personnes qui ont écrit l'implémentation du langage connaissaient et ont trouvé de bons moyens de les gérer. Mais vous vous heurtez à un cas de bord que l'implémentateur n'a pas pris en compte et vous voyez les performances se dégrader rapidement car l'interpréteur est obligé de prendre le code beaucoup plus littéralement et de le gérer de manière moins efficace.
la source
I rarely hit an edge case in any of them that couldn't be solved within the framework.
Oui, c'est tout l'intérêt: avoir à trouver un moyen de les résoudre dans le cadre, car le cadre n'est pas assez intelligent pour le résoudre pour vous comme vous l'aviez déclaré à l'origine.J'y pensais il y a quelques jours après une optimisation SQL. Je pense que nous pouvons convenir que SQL est un "langage déclaratif" dans la définition de Wikipedia:
Si vous pensez combien de choses se font derrière les rideaux (regarder les statistiques, décider si un index est utile, opter pour une jointure imbriquée, fusionnée ou de hachage, etc.), nous devons admettre que nous donnons juste un niveau élevé logique, et la base de données a pris en charge toute la logique de flux de contrôle de bas niveau.
Dans ce scénario également, l'optimiseur de base de données a parfois besoin de "conseils" de l'utilisateur pour obtenir les meilleurs résultats.
Une autre définition courante du langage "déclaratif" est (je ne trouve pas de source autoritaire):
Si nous acceptons cette définition, nous rencontrons les problèmes décrits par le PO.
Le premier problème est que SQL nous donne plusieurs façons équivalentes de définir "le même résultat". C'est probablement un mal nécessaire: plus nous donnons de pouvoir expressif à une langue, plus elle a probablement différentes manières d'exprimer la même chose.
Par exemple, on m'a demandé une fois d'optimiser cette requête:
Étant donné que les types étaient beaucoup moins que le client et qu'il y avait un index sur la
cust_type
table client, j'ai réalisé une grande amélioration en le réécrivant comme suit:Dans ce cas spécifique, lorsque j'ai demandé au développeur ce qu'il voulait réaliser, il m'a répondu "Je voulais tous les types de clients pour lesquels j'avais au moins un client", c'est d'ailleurs exactement la description de la requête de l'optimiseur.
Donc, si je pouvais trouver une requête équivalente et plus efficace, pourquoi l'optimiseur ne peut-il pas faire de même?
Ma meilleure supposition est que c'est pour deux raisons principales:
SQL exprime la logique:
puisque SQL exprime une logique de haut niveau, voudrions-nous vraiment que l'optimiseur nous «surpasse» nous et notre logique? Je crierais avec enthousiasme "oui" si ce n'était pour toutes les fois où je devais forcer l'optimiseur à choisir le chemin d'exécution le plus efficace. Je pense que l'idée pourrait être de permettre à l'optimiseur de faire de son mieux (révisant également notre logique) mais de nous donner un "mécanisme de conseil" pour venir à la rescousse quand quelque chose devient fou (ce serait comme avoir la roue + les freins dedans) une voiture autonome).
Plus de choix = plus de temps
Même le meilleur optimiseur RDBMS ne teste pas TOUS les chemins d'exécution possibles, car ils doivent être très rapides: à quel point serait-il bon d'optimiser une requête de 100 ms à 10 ms si je dois passer chaque fois 100 ms à choisir le meilleur chemin? Et c'est avec l'optimiseur respectant notre "logique de haut niveau". S'il devait également tester toutes les requêtes SQL équivalentes, le temps de l'optimiseur pourrait augmenter plusieurs fois.
Un autre bon exemple de réécriture de requête que le SGBDR n'est pas capable de faire est (à partir de cet article de blog intéressant )
que ce qui peut être écrit comme ceci (fonctions analytiques requises)
la source