Вероятно всяка връзка извършва пълно сканиране на таблицата на profiles
. Нека се опитаме да избегнем това. Когато има десетки заявки, удрящи една и съща таблица, има ключалки, които карат InnoDB да се „препъне в себе си“. Всеки от тези планове едновременно ще ускори заявката и ще намали броя на докоснатите редове (следователно ще намали заключването). Използването на предложения "композитен" индекс ще ускори заявката. Но OR
пречи на пътя. Виждам два трика, за да имам все още преглед на индекса на uniquestring
, но избягвайте някои или всички OR
.
( (prfls.uniquestring like 'phk5600dcc%')
or (prfls.uniquestring like 'phk5600dcf%')
)
OR
е трудно да се оптимизира.
Добавете това:
INDEX(isconnected, isprofilepresent, uniquestring)
Тогава...
План А:
prfls.uniquestring like 'phk5600dc%' AND -- note common prefix
( (prfls.uniquestring like 'phk5600dcc%')
or (prfls.uniquestring like 'phk5600dcf%')
)
Това предполага, че можете да създадете този общ префикс.
План Б (завъртете OR
в 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
План А (ако е практически) се възползва от това, което изглежда да бъде обща начална стойност. План Б работи независимо, но вероятно е малко по-бавен, макар и все още много по-бърз от оригинала.
Други бележки...
Индексите на флаговете (от които имате два) почти никога не се използват. EXPLAIN SELECT ...
вероятно ще покаже, че нито едно от двете не е използвано. Моля, предоставете EXPLAIN
за произволен SELECT
това се нуждае от обсъждане.
UNIQUE KEY
е KEY
, така че няма нужда от излишния индекс на USERID
.
limit 450
-- Кои 450 искаш? Без ORDER BY
, заявката може да ви даде всякакво 450. (Разбира се, може би това е добре.) (И ORDER BY
вероятно ще забави заявката.)
Моите предложения няма да „решат“ проблема, но трябва да увеличат броя на връзките, преди забавянето да стане забележимо.