Förmodligen gör varje anslutning en fullständig tabellsökning av profiles
. Låt oss försöka undvika det. När det finns dussintals frågor som träffar samma tabell, finns det lås som gör att InnoDB "snubblar över sig själv". Båda dessa planer kommer både att påskynda frågan och minska antalet rader som rörs (därav minska låsningen). Användningen av det föreslagna "sammansatta" indexet kommer att påskynda frågan. Men OR
kommer i vägen. Jag ser två knep för att fortfarande ha en indexkoll på uniquestring
, men undvik några eller alla OR
.
( (prfls.uniquestring like 'phk5600dcc%')
or (prfls.uniquestring like 'phk5600dcf%')
)
OR
är svårt att optimera.
Lägg till detta:
INDEX(isconnected, isprofilepresent, uniquestring)
Sedan...
Plan A:
prfls.uniquestring like 'phk5600dc%' AND -- note common prefix
( (prfls.uniquestring like 'phk5600dcc%')
or (prfls.uniquestring like 'phk5600dcf%')
)
Detta förutsätter att du kan konstruera det vanliga prefixet.
Plan B (sväng OR
till 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 (om praktiskt) drar fördel av vad verkar vara ett vanligt utgångsvärde. Plan B fungerar oavsett, men är förmodligen lite långsammare, fast ändå mycket snabbare än originalet.
Andra anteckningar...
Index på flaggor (varav du har två) används nästan aldrig. EXPLAIN SELECT ...
kommer förmodligen att visa att ingendera användes. Ange EXPLAIN
för valfri SELECT
som behöver diskussion.
En UNIQUE KEY
är en KEY
, så det finns inget behov av det redundanta indexet på USERID
.
limit 450
-- Vilken 450 vill du ha? Utan en ORDER BY
, får frågan ge dig vilken som helst 450. (Naturligtvis, det kanske är bra.) (Och ORDER BY
skulle förmodligen sakta ner frågan.)
Mina förslag kommer inte att "lösa" problemet, men de bör öka antalet anslutningar innan avmattningen blir märkbar.