Kontrollera även om MySQL fortfarande utför en fullständig tabellsökning efter att du har lagt till ytterligare 2 000 eller så rader till dina user_metrics
tabell. I små tabeller är access-by-index faktiskt dyrare (I/O-mässigt) än en tabellskanning, och MySQL:s optimerare kan ta hänsyn till detta.
Tvärtemot mitt tidigare inlägg , visar det sig att MySQL också använder en kostnadsbaserad optimerare
, vilket är mycket goda nyheter - det vill säga förutsatt att du kör din ANALYZE
minst en gång när du tror att datavolymen i din databas är representativ av framtida daglig användning.
När du har att göra med kostnadsbaserade optimerare (Oracle, Postgres, etc.), måste du se till att regelbundet köra ANALYZE
på dina olika bord när deras storlek ökar med mer än 10-15%. (Postgres kommer att göra detta automatiskt åt dig, som standard, medan andra RDBMS:er kommer att överlåta detta ansvar till en DBA, d.v.s. dig.) Genom statistisk analys, ANALYZE
kommer att hjälpa optimeraren att få en bättre uppfattning om hur mycket I/O (och andra tillhörande resurser, såsom CPU, som behövs t.ex. för sortering) som kommer att vara involverade när man väljer mellan olika kandidatexekveringsplaner. Det gick inte att köra ANALYZE
kan resultera i mycket dåliga, ibland katastrofala planeringsbeslut (t.ex. att millisekundsfrågor tar, ibland timmar på grund av dåliga kapslade loopar på JOIN
s.)
Om prestandan fortfarande är otillfredsställande efter att ha kört ANALYZE
, då kommer du vanligtvis att kunna komma runt problemet genom att använda tips, t.ex. FORCE INDEX
, medan du i andra fall kan ha snubblat över en MySQL-bugg (t.ex. denna äldre , som kunde ha bitit dig om du använde Rails nested_set
).
Nu, eftersom du är i en Rails-app , kommer det att vara besvärligt (och motverka syftet med ActiveRecord
) för att skicka dina anpassade frågor med tips istället för att fortsätta använda ActiveRecord
-genererade sådana.
Jag hade nämnt det i vår Rails-applikation all SELECT
frågorna sjönk under 100 ms efter byte till Postgres, medan några av de komplexa kopplingarna genererade av ActiveRecord
skulle ibland ta så mycket som 15s eller mer med MySQL 5.1 på grund av kapslade loopar med inre tabellskanningar, även när index var tillgängliga. Ingen optimerare är perfekt, och du bör vara medveten om alternativen. Andra potentiella prestandaproblem att vara medveten om, förutom frågeplansoptimering, är låsning. Detta ligger dock utanför omfattningen av ditt problem.