Как сделать так, чтобы предложение ORDER BY с небольшим LIMIT (т.е. 20 строк за раз) быстро возвращалось, когда я не могу использовать индекс для удовлетворения порядка строк?
Допустим, я хотел бы получить определенное количество заголовков из таблицы 'узел' (упрощенно ниже). Кстати, я использую MySQL.
node_ID INT(11) NOT NULL auto_increment,
node_title VARCHAR(127) NOT NULL,
node_lastupdated INT(11) NOT NULL,
node_created INT(11) NOT NULL
Но мне нужно ограничить количество возвращаемых строк только теми, к которым у определенного пользователя есть доступ. Многие пользователи имеют доступ к большому количеству узлов. У меня есть эта информация, предварительно рассчитанная в большой справочной таблице (попытка упростить задачу), где первичный ключ охватывает оба столбца, а наличие строки означает, что группа пользователей имеет доступ к этому узлу:
viewpermission_nodeID INT(11) NOT NULL,
viewpermission_usergroupID INT(11) NOT NULL
Поэтому мой запрос содержит что-то вроде
FROM
node
INNER JOIN viewpermission ON
viewpermission_nodeID=node_ID
AND viewpermission_usergroupID IN (<...usergroups of current user...>)
... и я также использую GROUP BY или DISTINCT, чтобы узел возвращался только один раз, даже если две пользовательские группы пользователей имеют доступ к этому узлу.
Моя проблема в том, что предложение ORDER BY, которое сортирует результаты по дате создания или последней обновленной дате, по-видимому, не может использовать индекс, поскольку возвращаемые строки зависят от значений в другой таблице viewpermission.
Поэтому MySQL должен будет найти все строк, которые соответствуют критериям, а затем отсортировать их все самостоятельно. Если для конкретного пользователя существует один миллион строк, и мы хотим просмотреть, скажем, последние 100 или 100-200 строк, упорядоченных по последнему обновлению, БД необходимо выяснить, какой миллион строк может видеть пользователь, отсортировать весь этот набор результатов, прежде чем он сможет вернуть эти 100 строк, верно?
Есть ли какой-нибудь творческий способ обойти это? Я думал так:
- Каким-то образом добавить даты в таблицу поиска viewpermission, чтобы я мог построить индекс, содержащий даты, а также разрешения. Это возможность, я думаю.
Редактировать: Упрощенный вопрос
Возможно, я могу упростить вопрос, переписав его так:
Есть ли способ переписать этот запрос или создать индекс для следующего, чтобы индекс мог использоваться для упорядочения (а не только для выбора строк)?
SELECT nodeid
FROM lookup
WHERE
usergroup IN (2, 3)
GROUP BY
nodeid
Индекс в (usergroup) позволяет части WHERE удовлетворяться индексом, но GROUP BY принудительно создает временную таблицу и файловую сортировку для этих строк. Индекс на (nodeid) ничего не делает для меня, потому что для предложения WHERE нужен индекс с пользовательской группой в качестве первого столбца. Индекс on (usergroup, nodeid) вызывает временную таблицу и сортировку файлов, поскольку GROUP BY не первый столбец индекса, который может изменяться.
Какие-нибудь решения?