Почему раздел? По своей сути он не обеспечит никакой производительности.
Чтобы ускорить этот запрос, измените or
на union
:
( select * from cl_inbox
where (user=user1 and contact=user2 and userstatus<>2)
order by id limit ?,?
) UNION ALL
( select * from cl_inbox
where (user=user2 and contact=user1 and contactstatus<>2)
order by id limit ?,?
)
Теперь каждая часть может независимо использовать i_contact_user
или i_user_contact
. (Ваша версия должна была выполнить полное сканирование таблицы.) Это будет работать намного быстрее. Кстати, для этого запроса эти два индекса одинаково хороши. Если вам не нужны оба для других запросов, я предлагаю отказаться от одного из них. Индексы *status
(и другие «флаги»), вероятно, бесполезны, безусловно, бесполезны для этого запроса.
Следующая проблема: использование OFFSET
для разбивки на страницы проблематично c. А при переключении на UNION
он теперь не работает.
Итак, вместо этого «запомните, где вы остановились». Поскольку вы говорите order by id
, я предполагаю, что идентификаторы в порядке, желаемом пользовательского интерфейса? Удалите OFFSET
и используйте id
:
( select * from cl_inbox
where (user=user1 and contact=user2 and userstatus<>2)
AND id < $left_off
ORDER BY id DESC
LIMIT ?
) UNION ALL
( select * from cl_inbox
where (user=user2 and contact=user1 and contactstatus<>2)
AND id < $left_off
ORDER BY id DESC
LIMIT ?
)
ORDER BY id DESC
LIMIT ?
(Да, я намеренно повторяю ORDER BY
и LIMIT
.) И я взял на себя смелость перевернуть вещи - не надо Вы хотите последние сообщения первыми?
Дополнительные обсуждения: http://mysql.rjweb.org/doc.php/pagination
Если вы ожидаете, что у вас огромный стол и желание удалите «старые» записи, тогда мы можем поговорить о разбиении для облегчения старых строк. Но это единственное использование, которое я вижу для разбиения этой таблицы.