Pokud jde o výkon, tyto korelované poddotazy vám mohou sníst oběd. A zhltněte také svůj obědový box, u velkých sad, kvůli způsobu, jakým je MySQL zpracovává. Každý z těchto poddotazů se provede pro každý řádek vrácený ve vnějším dotazu. A to může být u velkých souborů velmi drahé.
Alternativním přístupem je použít inline zobrazení k zhmotnění toho, co se líbí a nelíbí u veškerého obsahu, a poté k tomu provést operaci spojení.
Tento přístup však může být také drahý, zvláště když potřebujete „počet hlasů“ pouze pro několik řádků obsahu z tisíce řádků. Často existuje predikát z vnějšího dotazu, který lze také začlenit do vloženého pohledu, aby se omezil počet řádků, které je třeba prozkoumat a vrátit.
Chceme použít OUTER spojení s tímto vloženým pohledem, takže vrátí výsledek ekvivalentní vašemu dotazu; vrací řádek z content
když v vote
nejsou žádné odpovídající řádky tabulka.
SELECT [... BUNCH OF FIELDS ...]
, COALESCE(v.likes,0) AS likes
, COALESCE(v.dislikes,0) AS dislikes
, COALESCE(v.myvote,'.Constants::NO_VOTE.') AS myvote
FROM content c
LEFT
JOIN ( SELECT vt.cId
, SUM(vt.vote = '.Constants::LIKE.') AS likes
, SUM(vt.vote = '.Constants::DISLIKE.') AS dislikes
, MAX(IF(vt.userId = '.USER_ID.',vt.vote,NULL)) AS myvote
FROM votes vt
GROUP
BY vt.cId
) v
ON v.cId = c.contentId
[... OTHER STUFF ... ]
Všimněte si, že dotaz vloženého zobrazení (s aliasem v
) se podívá na KAŽDÝ řádek z votes
stůl. Pokud potřebujete pouze podmnožinu, zvažte přidání vhodného predikátu (buď v klauzuli WHERE nebo jako JOIN do jiné tabulky). Z [... OTHER STUFF ...]
nic nenaznačuje ve vašem dotazu, zda vrací jen několik řádků z content
nebo pokud potřebujete všechny řádky, protože objednáváte podle likes
, atd.
Pro malý počet řádků vybraných z content
tabulky, použití korelovaných poddotazů (jako ve vašem dotazu) může být ve skutečnosti rychlejší než zhmotnění velkého inline pohledu a provedení operace spojení proti němu.
Ach... a pro oba dotazy je samozřejmé, že příslušný index na votes
tabulka s úvodním sloupcem cId
prospěje výkonu. U inline zobrazení nechcete, aby režie MySQL musela provádět filesort
operace na všech těchto řádcích pro provedení GROUP BY. A pro korelované poddotazy chcete, aby používaly skenování rozsahu indexu, nikoli úplné skenování.