Как сделать так, чтобы предложение 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, которое сортирует результаты по дате создания или последнего обновления, нет возможности использовать индекс, потому что возвращаемые строки зависят от значений в другой таблице разрешений на просмотр.
Поэтому MySQL должен будет найти все строки, которые соответствуют критериям, а затем отсортировать их все самостоятельно. Если для конкретного пользователя существует миллион строк, и мы хотим просмотреть, скажем, последние 100 или строки 100-200 при упорядочении по последнему обновлению, БД потребуется выяснить, какой миллион строк может видеть пользователь, отсортировать весь этот набор результатов, прежде чем он сможет вернуть эти 100 строк, верно?
Есть ли какой-нибудь творческий способ обойти это? Я думал в том же духе:
- Каким-то образом добавьте даты в таблицу поиска разрешений на просмотр, чтобы я мог построить индекс, содержащий даты, а также разрешения. Я думаю, это возможно.
Изменить: упрощенный вопрос
Возможно, я смогу упростить вопрос, переписав его так:
Есть ли способ переписать этот запрос или создать индекс для следующего, чтобы индекс можно было использовать для упорядочения (а не только для выбора строк)?
SELECT nodeid
FROM lookup
WHERE
usergroup IN (2, 3)
GROUP BY
nodeid
Индекс (группа пользователей) позволяет части WHERE удовлетворяться индексом, но GROUP BY принудительно использует временную таблицу и сортировку файлов для этих строк. Индекс на (nodeid) ничего для меня не делает, потому что предложению WHERE нужен индекс с группой пользователей в качестве первого столбца. Индекс по (usergroup, nodeid) вызывает временную таблицу и сортировку файлов, поскольку GROUP BY не является первым столбцом индекса, который может изменяться.
Любые решения?