Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment optimiser cette requête MySQL ? Des millions de lignes

Je créerais les index suivants (index b-tree):

analytics(user_id, source, id) 
transactions(analytics, status)

Ceci est différent de la suggestion de Gordon.

L'ordre des colonnes dans l'index est important.

Vous filtrez par analytics.user_id spécifique , ce champ doit donc être le premier de l'index.Ensuite, vous regroupez par analytics.source . Pour éviter de trier par source cela devrait être le champ suivant de l'index. Vous faites également référence à analytics.id , il est donc préférable que ce champ fasse partie de l'index, placez-le en dernier. MySQL est-il capable de lire uniquement l'index et de ne pas toucher à la table ? Je ne sais pas, mais c'est plutôt facile à tester.

Index sur transactions doit commencer par analytics , car il serait utilisé dans le JOIN . Nous avons également besoin de status .

SELECT 
    analytics.source AS referrer, 
    COUNT(analytics.id) AS frequency, 
    SUM(IF(transactions.status = 'COMPLETED', 1, 0)) AS sales
FROM analytics
LEFT JOIN transactions ON analytics.id = transactions.analytics
WHERE analytics.user_id = 52094 
GROUP BY analytics.source 
ORDER BY frequency DESC 
LIMIT 10