`guid` CHAR(50) - плохой PK.
1. Он присутствует в каждом индексе и ест много памяти, метров так по 400 на индекс в вашем случае. А в этой памяти могли бы лежать данные, за которыми не пришлось бы лезть на диск. Выход - сделать PK int autoincrement, а guid - unique key.
2. Не знаю, как guid генерируется у вас, но могу предположить, что он равномерно распределённый, в таком случае строки вставляются в случайные места таблицы, что приводит к большому количеству seek при выборке. К тому же память buffer bool расходуется неэффективно в таком случае. В сочетании с п.1 - совсем беда. Выход тот же - pk int autoincrement. Вдобавок пронумеровать строки в порядке возрастания date (предполагаю, что у вас более часто запрашиваются недавние тексты) и дефрагментировать таблицу.
Также вызывает подозрения индекс (date, category) - при поиске по интервалу дат индекс не будет использоваться для категорий, ибо секунды.