Sandsynligvis laver hver forbindelse en fuld tabelscanning af profiles
. Lad os prøve at undgå det. Når der er snesevis af forespørgsler, der rammer den samme tabel, er der låse, der får InnoDB til at "snuble over sig selv". Hver af disse planer vil både fremskynde forespørgslen og reducere antallet af berørte rækker (derfor mindske låsningen). Brugen af det foreslåede "sammensatte" indeks vil fremskynde forespørgslen. Men OR
kommer i vejen. Jeg ser to tricks til stadig at se på uniquestring
, men undgå nogle af eller alle OR
.
( (prfls.uniquestring like 'phk5600dcc%')
or (prfls.uniquestring like 'phk5600dcf%')
)
OR
er svært at optimere.
Tilføj dette:
INDEX(isconnected, isprofilepresent, uniquestring)
Så...
Plan A:
prfls.uniquestring like 'phk5600dc%' AND -- note common prefix
( (prfls.uniquestring like 'phk5600dcc%')
or (prfls.uniquestring like 'phk5600dcf%')
)
Dette forudsætter, at du kan konstruere det almindelige præfiks.
Plan B (drej OR
ind i UNION
):
( SELECT ...
WHERE prfls.uniquestring like 'phk5600dcc%' AND ...
LIMIT 450 )
UNION ALL -- ? You may want DISTINCT, if there could be dups
( SELECT ...
WHERE prfls.uniquestring like 'phk5600dcf%' AND ... -- the only diff
LIMIT 450 )
LIMIT 450 -- yes, again
Plan A (hvis praktisk) udnytter det synes at være en fælles startværdi. Plan B virker uanset, men er nok lidt langsommere, dog stadig meget hurtigere end originalen.
Andre bemærkninger...
Indeks på flag (som du har to af) bruges næsten aldrig. EXPLAIN SELECT ...
vil nok vise, at ingen af dem blev brugt. Angiv venligst EXPLAIN
for enhver SELECT
det kræver diskussion.
En UNIQUE KEY
er en KEY
, så der er ikke behov for det redundante indeks på USERID
.
limit 450
-- Hvilken 450 vil du have? Uden en ORDER BY
, har forespørgslen lov til at give dig hvilket som helst 450. (Selvfølgelig er det måske fint.) (Og ORDER BY
ville sandsynligvis bremse forespørgslen.)
Mine forslag vil ikke "løse" problemet, men de bør øge antallet af forbindelser, før afmatningen bliver mærkbar.