2017-02-16 7 views
-1

Я есть таблицы игроков, кланы и clanmembers который соединяет игроков к кланам. То, что я хочу сделать, - это запросить всех игроков с информацией о клане, независимо от их клана или нет, и отсортировать их по player.rank (с индексом).MySQL использует FileSort и приводит к снижению производительности

SELECT * FROM игроков LEFT JOIN clanmembers ON clanmembers.player = players.id LEFT JOIN кланами НА clanmembers.clan = clans.id ORDER BY ранга DESC LIMIT 0,100;

Запрос выше работает правильно, но по какой-либо причине он сканирует всю таблицу игроков (много строк), и запрос выполняется очень медленно. Если я ВЫБЕРИВАЮЩИХ игроков. * Вместо этого сканируются ракеты производительности и всего 100 строк, а не всех игроков.

Что я здесь делаю неправильно? Я не понимаю, почему добавление материала клана для выбора делает запрос проверкой всей таблицы игроков, когда соединения остаются одинаковыми.

редактировать: All indexes here.

редактировать 2: Query results (EXPLAIN) here

+0

Pls добавить результаты Объяснения для обоих запросов, а также список индексов на 2 таблиц и полей, которые они включают. – Shadow

+0

Добавлено в оригинальное сообщение. id_rank был добавлен из-за ответа Джави, но не работал. –

ответ

1

Похоже, добавив FORCE INDEX (ранг) устраняет проблему.

Старый и медленно:

SELECT * FROM players LEFT JOIN clanmembers ON clanmembers.player = players.id LEFT JOIN clans ON clanmembers.clan = clans.id ORDER BY rank DESC LIMIT 0,100; 

Новые и быстро:

SELECT * FROM players FORCE INDEX (rank) LEFT JOIN clanmembers ON clanmembers.player = players.id LEFT JOIN clans ON clanmembers.clan = clans.id ORDER BY rank DESC LIMIT 0,100 
1

Как вы присоединяетесь к player таблицу с другими таблицами (таким образом, фильтрация по player id) перед заказом, может быть, вы должны добавить player id к индексу. Что-то вроде этого:

CREATE INDEX index_name ON players (rank, id); 

И необязательно, если вы всегда упорядоченности в порядке убывания, что-то вроде этого:

CREATE INDEX index_name ON players (rank DESC, id); 
+0

player.id уже является первичным ключом, как и каждый столбец id в моих таблицах. Должен ли я добавлять id в индекс ранга или создавать абсолютно новый индекс с двумя столбцами (id и rank)? Имеет ли это какие-либо негативные последствия для производительности? –

+0

Почему игроки фильтруются с идентификатором перед заказом? Разве не было бы больше смысла, что вы запускаете запрос, который возвращает всех желаемых игроков, правильно сортируется, а затем просто просматривает другие таблицы для каждой строки. –

+0

Дополнительный индекс с обоими полями уменьшит производительность в запросах на модификацию, но улучшит выбор запросов. Внутри этого индекса каждый пользователь сортируется по рангу в порядке убывания, а также содержит идентификатор, поэтому ему не нужно заглядывать в полную таблицу. –