J'ai une requête complexe qui prend 700 ms pour fonctionner sur ma machine. J'ai constaté que le goulot d'étranglement est l'ordre Explique de requête: P> CREATE TABLE `customer_entity_varchar` (
`value_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Value Id',
`entity_type_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity Type Id',
`attribute_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Id',
`entity_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity Id',
`value` varchar(255) DEFAULT NULL COMMENT 'Value',
PRIMARY KEY (`value_id`),
UNIQUE KEY `UNQ_CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID` (`entity_id`,`attribute_id`),
KEY `IDX_CUSTOMER_ENTITY_VARCHAR_ENTITY_TYPE_ID` (`entity_type_id`),
KEY `IDX_CUSTOMER_ENTITY_VARCHAR_ATTRIBUTE_ID` (`attribute_id`),
KEY `IDX_CUSTOMER_ENTITY_VARCHAR_ENTITY_ID` (`entity_id`),
KEY `IDX_CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_VALUE` (`entity_id`,`attribute_id`,`value`),
CONSTRAINT `FK_CSTR_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID` FOREIGN KEY (`attribute_id`) REFERENCES `eav_attribute` (`attribute_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_CSTR_ENTT_VCHR_ENTT_TYPE_ID_EAV_ENTT_TYPE_ENTT_TYPE_ID` FOREIGN KEY (`entity_type_id`) REFERENCES `eav_entity_type` (`entity_type_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID` FOREIGN KEY (`entity_id`) REFERENCES `customer_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=131094 DEFAULT CHARSET=utf8 COMMENT='Customer Entity Varchar';
3 Réponses :
Dès maintenant votre requête est la suivante:
commande code> les lignes. li>
- alors
limite code> ing les lignes. li>
ol> J'effectueriez d'abord les jointures extérieures strictement nécessaires, puis commandez et limitant (réduire à 20 rangées), puis je ferais enfin tout le reste des jointures extérieures. En bref, je ferais: p>
- Effectuer d'abord une jointure externe gauche minimale gauche. C'est-à-dire deux tables seulement. Li>
- alors
commande code> les lignes. li>
- alors
limite code> les rangées. Cela produisent un maximum de 20 rangées. Li>
- Effectuez tout le reste des jointures extérieures. À ce stade, ce n'est plus des milliers de rangées, mais seulement 20. Li>
ol>
Ce changement devrait réduire massivement les exécutions "de la recherche clé unique". La requête modifiée ressemblera à: p> xxx pré> p>
Parce que les résultats SQL sont sans commande par définition, le SQL externe nécessite également une commande par e.firstname code> pour garantir des résultats cohérents?
Si la commande est vraiment requise, oui. À ce stade, il est déjà filtré à 20 rangées, il peut donc être inutile.
Typo mineur, en ligne 10 Remplacer **, Concat (AT_FirstName.Value ** avec **, Concat (prénom **
@Avebrahimi Typo Fixe.
Malheureusement, L'astuce consiste à rechercher à moindre coût quelles lignes sont à l'intérieur de ce Quelles rangées voulez-vous? Il me semble que cette requête récupérera leur ceci devrait donner aux vingt valeurs d'entité pertinentes. Essaye-le. Regardez son plan d'exécution. Ajoutez un index approprié à alors vous pouvez mettre cela à la fin de votre requête principale, juste avant l'ordre par. p> et les choses doivent être un peu plus rapides. p> p> Sélectionnez tout_mess_of_rows à partir de plusieurs_tables Commandez par One_Col Limit Small_Number CODE> est une performance notoire antiparatère. Pourquoi? Parce qu'il trie un grand ensemble de résultats, juste pour se défaire la plupart d'entre eux.
Limiter le petit nombre code>, puis récupérez uniquement ces lignes de la plus grande requête. P>
customer_entity.id code> valeurs. Mais il est difficile d'être sûr, vous devriez donc tester cette sous-requête. P>
Customer_entity Code> Si besoin d'être. Cet index pourrait être
(fiateName_aTtribute_id, prénomname_entity_id, prénomname_value) code> mais je devine. P>
Je suis d'accord avec les réponses précédentes, mais je veux mettre l'accent sur plus d'antidiatern: sur-noramlization. P>
Votre schéma est une variante curieuse (et inefficace) sur le modèle de schéma déjà mauvais. p>
Il y a peu d'avantages et un inconvénient dans la scission Une adresse doit être stockée comme quelques colonnes dans une seule table; No De même pour FirstName + Nom. P>
Customer_Address_entity_varchars code> sur 5 tables. De même pour
Customer_entity_varchar Code>. P>
joint code> à d'autres tables. P>
téléphone code> pourrait être un autre problème, puisque une personne / une entreprise / entité pourrait avoir plusieurs numéros de téléphone (cellule, maison, travail, fax, etc.). Mais c'est une histoire différente. P>
Optimisation d'une requête avec les jointures avec
Commander par code> peut être difficile. Si l'optimiseur MySQL accédait aux tables de la commande "Mauvais" Commander une tri algoritme est toujours requise .. Idéalement, l'optimiseur doit accéder à Customer_entity_varchachar en premier. . Pouvez-vous fournir des structures de table et une sortie explique?
Veuillez poster le plan d'exécution.
Il n'y a pas de filtrage dans cette requête: cela signifie que c'est essentiellement le traitement toutes les lignes b> du
Customer_entity code>. Combien de rangées a-t-elle?
Vous n'avez pas assez de renseignements pour vous aider. Veuillez lire ceci, en particulier la section sur la performance de la requête, puis Modifier Votre question. meta.stackoverflow.com/a/271056
@Impaler c'est la liste des utilisateurs, peut-être des milliers
Pouvez-vous publier un indigène mysql
expliquer code> sortie? De plus, nous manquons toujours des structures de table.
@Raymondnijland Expliquez-vous ajouté à la question.