2010-12-07 2 views
1

Existe-t-il un moyen (ou automatique) pour MySQL d'optimiser la moitié inférieure d'une requête UNION ALL si j'impose une instruction LIMIT sur le nombre de résultats qui doivent être retournés . Par exemple, si j'ai une requête en tant que tel:MySQL optimisera la moitié inférieure d'une requête union

SELECT ID FROM MyTable WHERE Match (NameColumn) Against ('seachterm') 
UNION ALL 
SELECT ID FROM MyTable WHERE (DescriptionColumn) Against ('seachterm') 
LIMIT 10; 

Si je lance cette requête et la première requête pour une correspondance au nom renvoie 15 résultats, il devrait y avoir aucune raison de courir même la deuxième requête, comme je ont déjà assez de résultats. Est-ce que MySQL optimise la deuxième requête, ou y a-t-il un moyen de lui dire de le faire? Basé sur l'exécution de la requête avec EXPLAIN EXTENDED à l'avant, il n'apparaît pas que la deuxième partie soit optimisée.

Répondre

1

Après un peu de test, il semble que même s'il affiche la deuxième requête dans la sortie "EXPLAIN", il n'exécute pas la seconde requête si nécessaire. Je fis la requête suivante:

SELECT ID FROM MyTable WHERE Match (NameColumn) Against ('seachterm') 
UNION ALL 
SELECT ID FROM MyTable WHERE (DescriptionColumn) Against ('seachterm') 
UNION ALL 
SELECT ID FROM MyTable WHERE DescriptionColumn LIKE '%seachterm%' 
LIMIT 10; 

Maintenant, dans un tableau avec 3 millions de lignes, la dernière requête devrait prendre beaucoup de temps (et je l'ai testé seul, et il prend beaucoup de temps), mais lorsqu'il est ajouté Dans le cadre d'une union, il ne ralentit pas du tout la requête, car il n'est même pas nécessaire de l'exécuter, car nous obtenons suffisamment de lignes à partir des deux premières instructions. Si j'augmente la limite à un plus grand nombre de sorte que je ne reçois pas assez de résultats des deux premières requêtes, la troisième requête entre en jeu et commence à ralentir considérablement la requête.

+0

À quelle vitesse la dernière requête est-elle indépendante, mais avec 'LIMIT 10'? Parce que l'optimisation pourrait être plus dans les régions de: "si les résultats des requêtes" UNION "sont limitées à" n "lignes, chacune des requêtes peut être limitée à" n "lignes". – ontrack

+0

Cela dépendrait vraiment de la rapidité avec laquelle les lignes ont été trouvées. Comme il s'agit d'une analyse de table, si les 10 premières lignes contenaient la chaîne recherchée, elle retournerait très vite. Cependant, si la table ne contenait pas du tout la chaîne, cela prendrait beaucoup de temps car il faudrait faire une analyse de table sur toutes les données. – Kibbee

0

Avec votre requête réelle, est-il possible de faire quelque chose comme ça? (non testé)

select id 
     ,case when nameColumn  like '%Product X%' then 1 
      when DescriptionColumn like '%Product X%' then 2 
     end as priority 
    from MyTable 
where nameColumn  like '%Product X%' 
    or DescriptionColumn like '%Product X%' 
order by priority 
limit 10; 

Modifier
Je lis à nouveau votre question et réalisé que je missunderstood la question. Je pensais que vous vous demandez comment hiérarchiser les correspondances de noms sur les correspondances de description. Je laisse le code en place, au cas où il apparaîtrait sur le haut rendement sage de toute façon.