Utworzyłbym następujące indeksy (indeksy b-drzewa):
analytics(user_id, source, id)
transactions(analytics, status)
Różni się to od sugestii Gordona.
Kolejność kolumn w indeksie jest ważna.
Filtrujesz według określonego analytics.user_id
, więc to pole musi być pierwsze w indeksie. Następnie grupujesz według analytics.source
. Aby uniknąć sortowania według source
powinno to być następne pole indeksu. Odwołujesz się również do analytics.id
, więc lepiej mieć to pole jako część indeksu, umieść je na końcu. Czy MySQL może czytać tylko indeks i nie dotykać tabeli? Nie wiem, ale dość łatwo to przetestować.
Indeks transactions
musi zaczynać się od analytics
, ponieważ zostałby użyty w JOIN
. Potrzebujemy również 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