J'ai travaillé pour différentes entreprises, et j'ai remarqué que certaines d'entre elles préfèrent avoir des vues qui rejoindront une table avec tous ses "proches". Mais ensuite sur l'application quelques fois, nous n'avons besoin que d'une seule colonne.
Serait-il donc plus rapide de faire simplement des sélections simples, puis de les "joindre" sur le code système?
Le système peut être php, Java, asp, n'importe quel langage qui se connecte à la base de données.
La question est donc de savoir ce qui est plus rapide pour passer d'un côté serveur (php, Java, asp, Ruby, python ...) à la base de données, exécuter une requête qui obtient tout ce dont nous avons besoin ou passer du côté serveur à la base de données et exécuter un requête qui n'obtient que les colonnes d'une table à la fois?
Ce qui répondrait à votre question est le sujet REJOINDRE LA DÉCOMPOSITION.
Selon page 209 du livre
Vous pouvez décomposer une jointure en exécutant plusieurs requêtes à table unique au lieu d'une jointure multitable, puis en effectuant la jointure dans l'application. Par exemple, au lieu de cette seule requête:
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id = tag.id
JOIN post ON tag_post.post_id = post.id
WHERE tag.tag = 'mysql';
Vous pouvez exécuter ces requêtes:
SELECT * FROM tag WHERE tag = 'mysql';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id IN (123,456,567,9098,8904);
Pourquoi diable feriez-vous cela? Cela semble inutile à première vue, car vous avez augmenté le nombre de requêtes sans rien obtenir en retour. Cependant, une telle restructuration peut en fait offrir des avantages de performance importants:
mysql
est déjà mis en cache, l'application ignorera la première requête. Si vous trouvez des publications avec un ID de 123, 567 ou 908 dans le cache, vous pouvez les supprimer de la liste IN()
. Le cache de requêtes peut également bénéficier de cette stratégie. Si une seule des tables change fréquemment, la décomposition d'une jointure peut réduire le nombre d'invalidations du cache.IN()
au lieu d'une jointure permet à MySQL de trier les ID de ligne et de récupérer les lignes de manière plus optimale qu'il ne serait possible avec une jointure.Par conséquent, faire des jointures dans l'application peut être plus efficace lorsque vous mettez en cache et réutilisez un grand nombre de données provenant de requêtes antérieures, vous distribuez des données sur plusieurs serveurs, vous remplacez les jointures par des listes IN()
, ou une jointure fait référence à la même table plusieurs fois.
J'aime le premier point parce qu'InnoDB est un peu lourd lorsqu'il vérifie le cache des requêtes.
Sep 05, 2012
: La surcharge d'invalidation fréquente du cache de requêtes en vaut-elle la peine?Jun 07, 2014
: Pourquoi query_cache_type est désactivé par défaut à partir de MySQL 5.6?En ce qui concerne le dernier point, j'ai écrit un article le 11 mars 2013 ( y a-t-il une différence d'exécution entre une condition JOIN et une condition WHERE? ) qui décrit l'algorithme de boucle imbriquée. Après l'avoir lu, vous verrez à quel point la décomposition des jointures peut être bonne.
Comme pour tous les autres points du livre , les développeurs recherchent vraiment la performance comme résultat. Certains s'appuient sur des moyens externes (en dehors de l'application) pour des améliorations de performances telles que l'utilisation d'un disque rapide, l'obtention de plus de CPU/cœurs, le réglage du moteur de stockage et le réglage du fichier de configuration. D'autres vont boucler et écrire un meilleur code. Certains peuvent avoir recours au codage de l'intelligence d'affaires dans les procédures stockées mais n'appliquent toujours pas la décomposition des jointures (voir Quels sont les arguments contre ou pour mettre la logique d'application dans la couche de base de données? avec les autres messages). Tout dépend de la culture et de la tolérance de chaque boutique de développeur.
Certains peuvent être satisfaits des performances et ne plus toucher au code. D'autres ne réalisent tout simplement pas qu'il existe de grands avantages que l'on peut retirer s'ils essaient de se joindre à la composition.
Pour les développeurs qui le souhaitent ...
Dans Postgres (et probablement n'importe quel SGBDR dans une mesure similaire, MySQL dans une moindre mesure), moins de requêtes sont presque toujours beaucoup plus rapide.
La surcharge de l'analyse et de la planification de plusieurs requêtes est déjà plus que tout gain possible dans la plupart des cas.
Sans parler du travail supplémentaire à faire chez le client, en combinant les résultats, ce qui est généralement beaucoup plus lent à cela. Un SGBDR est spécialisé dans ce type de tâche et les opérations sont basées sur des types de données originaux. Pas de transtypage vers text
et retour pour des résultats intermédiaires ou transformation en types natifs du client, ce qui peut même conduire à des résultats moins corrects (ou incorrects!). Pensez aux nombres à virgule flottante ...
Vous transférez également plus de données entre le serveur de base de données et le client. Cela peut être négligeable pour une main pleine de valeurs, ou faire une énorme différence.
Si plusieurs requêtes signifient plusieurs allers-retours vers le serveur de base de données, vous collectez également plusieurs fois la latence du réseau et la surcharge de transaction, voire la surcharge de connexion. Grande, grosse perte.
Selon votre configuration, la latence du réseau à elle seule peut prendre plus de temps que tous les autres par ordre de grandeur.
Question connexe sur SO:
Il peut y avoir un tournant pour très grand, des requêtes de longue durée car les transactions collectent des verrous sur les lignes de base de données en cours de route. Les requêtes très volumineuses peuvent contenir de nombreux verrous pendant une période prolongée, ce qui peut provoquer des frictions avec requêtes simultanées.