Оба запроса делают все возможное с тем, что вы им дали.
select *
from users u
join wallet w ON w.userId=u.uuid
where w.userId='8319611142598331610';
select *
from users u
join wallet w ON w.userId=u.uuid
where w.currencyId=8;
Если в таблице только одна строка (например, users
), оптимизатор выбирает другой путь. Похоже, именно это и произошло с первым запросом.
В противном случае оба запроса начнутся с wallet
, поскольку происходит фильтрация. Каждый из вторичных ключей в wallet
удобен для одного из запросов. Еще лучше было бы
INDEX(userId, currencyId, id) -- for first query
INDEX(currencyId, userId, id) -- for second query
Первый столбец используется в WHERE
; два других столбца делают индекс «покрывающим», так что ему не нужно прыгать между индексом и данными.
(Боже, у этих таблиц ужасно мало столбцов.)
После фильтрации в w
он переходит к u
и использует INDEX(uuid)
. Поскольку это единственный столбец в таблице (без имени ??), это может быть «Использование индекса», то есть «покрытие».
И единственная причина для достижения u
состоит в том, чтобы убедиться, что существует пользователь со значением, совпадающим с w.userId
. Поскольку у вас это, вероятно, всегда есть, почему в запросе от JOIN
до users