J'ai travaillé pour différentes entreprises et j'ai remarqué que certaines d'entre elles préféraient avoir un point de vue qui rejoindrait une table avec tous ses "proches". Mais quelques fois sur l'application, nous n'avons besoin que d'une colonne.
Alors, serait-il plus rapide de simplement faire des sélections simples, puis de les "rejoindre" dans le code système?
Le système pourrait être php, java, asp, n'importe quelle langue qui se connecte à la base de données.
La question est donc de savoir ce qui est plus rapide pour passer du côté serveur (php, java, asp, ruby, python ...) à la base de données, exécuter une requête qui obtienne tout ce dont nous avons besoin ou allant du côté serveur à la base de données et exécuter un requête qui obtient seulement les colonnes d'une table à la fois?
la source
Réponses:
Ce qui répondrait à votre question est le sujet JOIN DECOMPOSITION.
Selon la 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 requête unique:
Vous pourriez exécuter ces requêtes:
Pourquoi diable ferais-tu 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 réalité offrir des avantages significatifs en termes de performances:
mysql
est déjà mis en cache, l'application ignorera la première requête. Si vous trouvez des publications avec un identifiant de 123, 567 ou 908 dans le cache, vous pouvez les supprimer de laIN()
liste. Le cache de requêtes pourrait é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()
liste 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'avec une jointure.En conséquence, les jointures des actions dans l'application peuvent être plus efficaces lorsque vous mettez en cache et réutilisez une grande quantité de données de requêtes précédentes, que vous répartissez les données sur plusieurs serveurs, que vous remplacez les jointures par des
IN()
listes ou que la jointure fait référence à la même table plusieurs fois.OBSERVATION
J'aime le premier point parce qu'InnoDB est un peu lourd lorsqu'il vérifie le cache de requêtes.
Sep 05, 2012
: La surcharge liée à l'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 depuis MySQL 5.6?En ce qui concerne le dernier point, j'ai écrit un article le 11 mars 2013 ( Existe-t-il une différence d'exécution entre une condition JOIN et une condition WHERE? ) Décrivant l'algorithme de la boucle imbriquée. Après l'avoir lu, vous verrez à quel point la décomposition des jointures est efficace.
Comme pour tous les autres points du livre , les développeurs recherchent vraiment la performance comme résultat. Certaines s'appuient sur des moyens externes (en dehors de l'application) pour améliorer les performances, telles que l'utilisation d'un disque rapide, l'obtention de davantage de processeurs / cœurs, le réglage du moteur de stockage et le fichier de configuration. D'autres vont s'attacher et écrire un meilleur code. Certains peuvent recourir à la codification de toute l'intelligence d'affaires dans les procédures stockées, sans toujours appliquer la décomposition de jointure (voir Quels sont les arguments contre ou pour placer la logique d'application dans la couche base de données? Avec les autres publications). Tout dépend de la culture et de la tolérance de chaque développeur.
Certains peuvent être satisfaits des performances et ne plus toucher au code. D’autres ne réalisent tout simplement pas qu’il ya de grands avantages à tirer s’ils essaient de joindre la composition.
Pour les développeurs qui veulent ...
ESSAIE !!!
la source
Dans Postgres (et probablement dans n'importe quel SGBDR, MySQL dans une moindre mesure), moins de requêtes sont presque toujours beaucoup plus rapides.
La surcharge liée à l'analyse et à la planification de plusieurs requêtes représente déjà un avantage non négligeable dans la plupart des cas.
Sans parler du travail supplémentaire à effectuer chez le client, combinant les résultats, ce qui est généralement beaucoup plus lent. Un SGBDR est spécialisé dans ce type de tâche et les opérations sont basées sur les types de données d'origine. Aucune conversion vers
text
et en arrière pour des résultats intermédiaires ou une conversion 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 davantage 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 et retours vers le serveur de base de données, vous collectez également plusieurs fois la latence du réseau et la surcharge de la transaction, voire la connexion. Grosse, grosse perte.
Selon votre configuration, la latence du réseau à elle seule peut prendre plus longtemps que tous les autres, par ordre de grandeur.
Question connexe sur SO:
Il peut y avoir un tournant pour les requêtes très volumineuses et longues, car les transactions collectent des verrous sur les lignes de base de données en chemin. Les très grandes requêtes peuvent conserver de nombreux verrous pendant une période prolongée, ce qui peut entraîner des frictions avec des requêtes simultanées .
la source
returns lots of redundant data for "parent" table
: Pourquoi renverriez-vous des données redondantes? Renvoyez uniquement les données dont vous avez besoin.