2011-09-03 8 views
1

J'utilise une requête UNION pour extraire des données de deux tables en fonction de la date. Requête ci-dessousOptimiser une requête mysql UNION

SELECT title, id, date as date_added 
FROM test1 WHERE test1.id 
UNION 
SELECT title, customer as id, date_added  
FROM test2 WHERE test2.id 
ORDER BY date_added DESC LIMIT 0,8 

J'ai un index sur la date et DATE_ADDED sur chaque table ... le problème est que la requête n'est pas optimisé et quand je l'utilise EXPLIQUER il montre toutes les lignes des deux tables sont sélectionnés pour me donner la sortie.

Existe-t-il une autre façon de faire cette requête afin qu'elle puisse être optimisée? La seule solution que je peux penser est d'exécuter les deux requêtes séparément avec LIMITS et de trier les données dans l'application, mais il semble qu'il serait impossible d'effectuer la pagination dans mon application avec cela.

+0

Votre condition 'WHERE' semble un peu tronquée dans le but de limiter les lignes sélectionnées. Avez-vous omis quelque chose? –

+0

Non, je n'ai pas. Même si je supprime la clause where, les requêtes sélectionnées sont toujours égales au nombre total de lignes dans chaque table. – user350230

+1

Eh bien, ils le feraient, n'est-ce pas. Vous n'avez pas d'égalité ou d'autre terme pour limiter l'instruction WHERE, si ce n'est que " .id" doit contenir une valeur qui vaut true. Normalement, il aurait un terme limitant comme «colonne = valeur» ou «colonne» valeur »ou« colonne entre valeur1 et valeur2 », etc. –

Répondre

0

Je ne suis pas le meilleur expert, mais je suppose qu'en raison de la UNION mysql doit sélectionner et fusionner les deux ensembles de résultats avant d'effectuer l'ING ORDER, et donc, l'optimisation du jeu potentiel de résultat qui pourrait être fournie par la clause LIMIT, ne se produit pas.

Peut-être que cette question peut s'appliquer à votre cas ainsi:

Combining UNION and LIMIT operations in MySQL query

2

Ce que vous montrez fondamentalement est que vous avez un problème de conception dans votre modèle où il semble que le mauvais choix a été fait quand implemententing super/sous-types. Votre exigence fonctionnelle consiste à avoir des données (simulées) provenant de deux tables différentes sous la forme d'un ensemble uniforme. Ce serait simple si toutes ces rangées avaient été dans une table. La vraie question est pourquoi ils ne le sont pas.

Vous pouvez toujours obtenir cette requête plus rapidement (je suppose) mais c'est moche.

SELECT * FROM 
    (SELECT * FROM (select title, id, date as date_added from test1 
        ORDER BY date_added DESC LIMIT 0,8) t1 
    UNION ALL 
    SELECT * FROM (select title, customer as id, date_added from test2 
        ORDER BY date_added DESC LIMIT 0,8) t2 
    ) joined 
ORDER BY date_added DESC 
LIMIT 0,8