La structure de la table est la suivante:
1 SIMPLE test index_merge PRIMARY,one,two,three,four one,two 5,5 30 Using sort_union(one,two); Using where; Using filesort
6 Réponses :
Si votre version MySQL est inférieure à 5.0.7, le problème MySQL peut être une raison p>
regarder ce billet dans MySQL Bug suivi https://bugs.mysql.com /bug.php?id=10561 p>
Mélange L'idée est de le casser sur des conditions plus petites afin que mysql puisse utiliser différents index optimisé pour chaque partie plutôt que par opposition à la barrage ensemble. p> et code> et ou code> causerait souvent un plan de requête étrange sur MySQL, dans mon expérience. Je n'ai pas assez de données sur la table pour tester, mais j'essaierais de réécrire votre requête en utilisant Union tout code>. Après tout, ou code> dans où code> est fondamentalement union code>.
Il serait bon d'avoir une vidange de données d'échantillonnage à tester, mais j'ai créé certains de moi-même. Ensuite, j'ai divisé chacun des quatre extérieurs dans des sous-requêtes, les syndiquées et déplacé la commande à l'ensemble de résultats final.
J'ai eu des problèmes avec des index lors de l'utilisation complexe où les clauses et pour moi il ressemble à vous Avoir une application de chat / messagerie et essayez d'obtenir des messages vers et depuis un utilisateur particulier dans une seule requête. Personnellement, je les scinderais en requêtes individuelles pour simplifier le code / les requêtes. P>
Voici ma requête: p>
Je ne suis pas sûr de savoir pourquoi cela ne fonctionne pas correctement. Qu'est-ce que je manque dans les index? P>
Je suis sûr que le planificateur de requête fonctionne parfaitement, vous ne manquez rien dans les index qui aideraient dans ce cas. Le planificateur de requêtes a décidé qu'il serait plus rapide d'utiliser un index différent car les deux requêtes sont très différentes. P>
Nous pouvons rendre l'optimiseur à utiliser une union des index pour nous qui le rendra considérablement plus rapide. Vous pouvez conserver le
pas dans code> et ne pas modifier l'une des déclarationsou code>. J'ai dirigé des repères de base de la méthode que j'ai utilisée contre la méthode de l'Union. Les mises en garde s'appliquent car votre configuration de DB peut être très différente du mien. Exécution de la requête A 1000 fois et cela 3 fois, j'ai pris le meilleur temps pour chaque requête ... p>requête optimisée indiquée ci-dessous b> p>
xxx Pré> réécrit comme un ensemble de syndicions b> p>
xxx pré> pense comme l'optimiseur et travaillez avec moins de données forte > p>
Le SQL suivant est plusieurs commandes de grandeur plus rapidement dans les tests sur une base de données d'environ 4 millions de lignes. Le changement de clé est la ligne suivante p>
xxx pré> Cette ligne est vaste, réduisant énormément l'ensemble de données que MySQL doit fonctionner car nous utilisons
dans code> depas dans code>. Ceci est la nouvelle requête, j'ai essayé de ne pas trop changer la requête d'origine. P>1. I don't want these 10 items from a 1,000,000 records I need the other 999,990, this reads the whole index. 2. I only want these 10 from a 1,000,000 records. This might only require one disk seek.
Heureux d'avoir pu aider. Si vous voulez d'autres idées sur la façon de syntoniser ce qui précède, il y a de meilleurs indices que vous pouvez utiliser. Vous ne gagnerez pas grand chose, mais si l'optimiseur leur choisit, il y a une forte probabilité qu'ils soient plus optimales. Ils sont plus petits que les indices actuels et cela pourrait être le plus gros gain.
Ceci est probablement dû au niveau supplémentaire de nidification / complexité, le Le Index Merge Union Trier Votre 2e requête utilise convertit la clause WHERE dans un ensemble de conditions de plage a> combiné par Chaque valeur que vous comparez à l'aide de Comme le nombre de prédicats augmente, à un moment donné, l'optimiseur décide qu'il est plus rapide de simplement numériser toute la table. P> dans code> sur une colonne supplémentaire ajoute à votre clause WHERE. p>
ou code>. p>
dans code> comporte comme un autre prédicat de plage, en ajoutant les deux conditions code> dans code> avec 8 valeurs chacune à votre première requête ajoute 64 prédicats supplémentaires. p>
commencez par ce supposer que la sous-requête a beaucoup moins de lignes que maintenant, pour Utilisez "Evaluation paresseuse" pour accélérer plus: P> test code>, cela peut fonctionner plus rapidement. P> PRIMARY KEY(id)
INDEX(from, id)
INDEX(to, id)
Oui. Cela fait longtemps. (Vous avez une requête méchante ici. La vraie solution peut impliquer de repenser le schéma.)
Je sais que c'est méchant mais je pense que l'OP sait que aussi, il a suffisamment de représentant que je suppose qu'il sait ce qu'il fait. La question pose pourquoi le pas dans code> cause des problèmes et j'ai essayé de résoudre ce problème. La requête / schéma peut être abordée de nombreuses manières. Je serai de retour dans quelques heures, c'est un petit monde. J'étais à Ysports et j'aimais là-bas.
@Harry Oui, au courant de la requête Nasty :(
Comme déjà mentionné, ou code> est un tueur de couple qui conduit effectivement à des analyses de table. pas dans (Sélectionnez ...) CODE> est beaucoup pire que pas dans (1,2,3) code> en raison des appels répétés à la sous-requête.
Quelle est la taille de votre table? Et pourriez-vous essayer d'utiliser
index de force (primaire) code> pour voir s'il y a un gain de performance?Avez-vous essayé d'utiliser NOT_EXIST ()?
Stackoverflow.com/Questions/6120100/MYSQL-NOT-IN -Query-optim ize
@Mani environ 4 millions d'enregistrements
@Alec sont les valeurs
204177, 214518, 231429, 242739, 243834, 244354, 244644, 244690 Code> Différent chaque fois que la requête s'exécute, ou constante? Si différent, à quelle fréquence le get est-il exécuté?C'est une requête très inhabituelle d'exécuter à plusieurs reprises. Comment as-tu fini ici? Il existe peut-être une autre approche de stockage de données qui pourrait atténuer la solution.
Combien d'enregistrements récupérez-vous après avoir utilisé
pas dans la condition code>? En l'aperçu, votrepas dans code> court-circuits votre autre "gros" conditions, ce qui vous laisse avec 2ou code> Conditions qui sont minuscules. Ayant utilisédirection code> qui semble avoir une cardinalité faible, cela oblige MySQL à numériser toutes les lignes pour satisfaire vos conditions de 2ou code>. C'est mes 2 cents, je sais que cela n'aide pas vraiment mais votreoù code> sont vraiment, vraiment laid :)@Bohemian Les valeurs changent à chaque fois
@alec Il est trop tard pour répondre maintenant, après la fin de la prime, si vous voulez de meilleures réponses. Vous devriez surveiller le site pour commentaires / questions, surtout s'il y a une prime en jeu