Comment Améliorer les Performances des Requêtes avec plusieurs Jointures
J'ai une requête (avec l'objectif de prise de vue) qui est à l'aide d'un peu de joint pour obtenir à chaque colonne. Les performances se dégradent rapidement (de façon exponentielle?) pour chaque ensemble de jointures ajouté.
Ce serait une bonne approche pour faire cette requête la plus rapide? Veuillez voir les commentaires à l'intérieur de la requête.
Si ça aide, c'est à l'aide de l'WordPress DB schéma.
Voici une capture d'écran de l'EXPLIQUER
les PRODUITS de la TABLE
+--+----+
|id|name|
+--+----+
|1 |test|
+--+----+
TABLE de MÉTADONNÉES
+----------+--------+-----+
|product_id|meta_key|value|
+----------+--------+-----+
|1 |price |9.99 |
+----------+--------+-----+
|1 |sku |ABC |
+----------+--------+-----+
TERM_RELATIONSHIPS TABLE
+---------+----------------+
|object_id|term_taxonomy_id|
+---------+----------------+
|1 |1 |
+---------+----------------+
|1 |2 |
+---------+----------------+
TERM_TAXONOMY TABLE
+----------------+-------+--------+
|term_taxonomy_id|term_id|taxonomy|
+----------------+-------+--------+
|1 |1 |size |
+----------------+-------+--------+
|2 |2 |stock |
+----------------+-------+--------+
CONDITIONS de TABLE
+-------+-----+
|term_id|name |
+-------+-----+
|1 |500mg|
+-------+-----+
|2 |10 |
+-------+-----+
REQUÊTE
SELECT
products.id,
products.name,
price.value AS price,
sku.value AS sku,
size.name AS size
FROM products
/* These joins are performing quickly */
INNER JOIN `metadata` AS price ON products.id = price.product_id AND price.meta_key = 'price'
INNER JOIN `metadata` AS sku ON products.id = sku.product_id AND sku.meta_key = 'sku'
/* Here's the part that is really slowing it down - I run this chunk about 5 times with different strings to match */
INNER JOIN `term_relationships` AS tr ON products.id = tr.object_id
INNER JOIN `term_taxonomy` AS tt
ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'size'
INNER JOIN `terms` AS size
ON tt.term_id = size.term_id
OR
peut tuer l'utilisation des index, essayer de réécrire l'aide d'une union.montrer la sortie de
DESC tableName
pour chaque table.ou au moins la sortie de
EXPLAIN <your SQL>;
voulez-vous dire
ON
? Je n'ai pas de OR
dans l'exemple.L'expliquer est sûr, c'est d'une requête différente! Tables vat 2, tt3 ne sont pas présents. -1 jusqu'à ce que vous corriger.
OriginalL'auteur dloewen | 2014-01-03
Vous devez vous connecter pour publier un commentaire.
Votre problème de performances est probablement causé par la jointure avec le " term_taxonomy table.
Tous les autres jointures semble utiliser la clé primaire (où vous probobly de travail d'index).
Donc, ma suggestion est d'ajouter un index composé sur term_taxonomy_id et term_id (ou si vous devez: taxonomie). Comme ceci:
Espère que cela va vous aider.
metadata (product_id, mate_key)
parce que d'avoir un large indice de diversité signifie qu'il ya plus d'options pour l'optimiseur mysql pour créer un meilleur plan d'exécution.Bingo! La création de l'index composé dans les métadonnées de la table sur product_id et meta_key fait la requête à exécuter en moins de 1 seconde, une énorme amélioration à partir de 30 secondes!
vous pouvez poster votre solution séparément afin que je puisse vous donner le bounty? Merci aussi carleson pour l'astuce qui conduisent à la solution.
Eh bien, je pense que carleson vous a donné la bonne direction et mon commentaire était juste 2 centimes afin de rendre sa réponse plus complète 🙂
OriginalL'auteur carleson
Assurez-vous que toutes les colonnes sur lesquelles il est "SUR" instructions conditionnelles est-il, doit être indexé.
Cela permettra d'améliorer de manière significative la vitesse.
OriginalL'auteur akkig
Je l'Espère, de la façon décrite ci-dessus permettra de réduire le temps d'utilisation, ou la création d'une table temporaire avec tous les champs que vous sélectionnez et mise à jour de la table temporaire en se joignant à la table temporaire pour tous les autres tables peuvent également être efficace, eh bien, je ne suis pas sûr à ce sujet, mais Même moi, je suis en attente de votre résultat comme votre question semble intéressant
OriginalL'auteur JB9
Essayez ceci:
Si vous trouvez toujours que votre requête est lent, puis ajouter le
EXPLAIN
plan de ma requête afin que je puisse trouver les colonnes besoinsINDEX
.OriginalL'auteur Saharsh Shah
Le script ci-dessous est mis en forme comme par SQL Server règles - Vous pouvez changer ce que par MySQL règles et essayez par vous -
Ce que je ressens pourrait être le goulot d'étranglement dans votre requête - Vous joindre à des Métadonnées 2 fois. Depuis il y a 1 à de nombreuses relations dans vos tables, les Métadonnées 2-rejoindre ne fait pas de mal, mais après que vous joindre plusieurs tables - le nombre de lignes en raison de 1 à plusieurs relations augmentation - et donc la prformance gouttes.
Ce que j'ai essayé de réaliser - je suis en train de faire que le plus grand nombre de 1 à 1 les relations sont remplies que possible. Pour ce faire, j'ai fait un Pivot sur les Métadonnées adn faites des prix & sku comme des colonnes. Maintenant, mon id de produit doit avoir une seule ligne dans les Métadonnées de pivot. alos, que j'ai fait en sorte que je me joins à cette picot à la fin.
Lui donner un essai. S'il vous plaît partager les attentes de performance, le nombre d'enregistrements que vous avez & aussi quelles sont les performances que vous obtenez avec ma asnwer.
OriginalL'auteur Suyash Khandwe
METADATA_TABLE et TERM_RELATIONSHIP_TABLE n'ont pas tout proimary clé. Quand il y a d'énormes dossiers de ces tables de votre requête performancy seront frappés.
De points de contrôle pour augmenter vos performances.
Si vous souhaitez améliorer les performances, créer non-clustered index de colonnes, telles que: *object_Id champ de term_relationships table* . Index Non-cluster doit être créé pour les colonnes de la table qui prennent part à l'opération de jointure.
Toutefois, le point à noter est que, index non-cluster doit être très inférieur à ceux des tables où plusieurs d'insertion et de mises à jour qui se passe.
Ce n'est pas une question simple et ne peut pas être traitée uniquement basé sur le moment de l'exécution. Il y a d'autres facteurs qui influent sur la réponse surtout si l'environnement où une procédure stockée est en cours d'exécution est fortement transactionnelle.
Vous pouvez trouver plus de ici
OriginalL'auteur gokul
Je dirais:
De mon expérience:
(Pardonnez-moi je n'ai pas fournir la solution pour améliorer les performances de votre requête.)
OriginalL'auteur Joshua