2016-08-31 3 views
1

У меня есть таблица сообщений чата, которая выросла до> 4 м строк.Оптимизация диапазона дат на большом столе

Мне нужно получить сообщения, отправленные пользователю и от пользователя в течение определенного диапазона дат.

Сначала этот запрос был одобрен, но с текущим размером таблицы он слишком длинный (> 10 с).

Я попытался создать множество комбинаций индексов; MySQL использует составной индекс для messageType + sentDate

SELECT `ofMessageArchive`.* 
FROM `ofMessageArchive` 
WHERE `ofMessageArchive`.`messageType` IN ('Message') 
AND (ofMessageArchive.fromJID = '[email protected]' OR ofMessageArchive.toJID = '[email protected]') 
AND (ofMessageArchive.sentDate > '1462235333109') 
ORDER BY ofMessageArchive.sentDate ASC LIMIT 50 

Любые идеи, как я могу оптимизировать этот запрос?

[EDIT] EXPLAIN результат:

+----+-------------+------------------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+---------+-------+--------+-------------+ 
| id | select_type | table   | type | possible_keys                                              | key     | key_len | ref | rows | Extra  | 
+----+-------------+------------------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+---------+-------+--------+-------------+ 
| 1 | SIMPLE  | ofMessageArchive | ref | index_ofMessageArchive_on_fromJID_and_toJID,index_ofMessageArchive_on_sentDate,index_ofMessageArchive_on_messageType,idxMessageTypeSentDate,ofMessageArchive_fromjid_idx,ofMessageArchive_tojid_idx | idxMessageTypeSentDate | 767  | const | 731570 | Using where | 
+----+-------------+------------------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+---------+-------+--------+-------------+ 
+1

Просьба EXPLAIN' результат этого запроса –

+0

Добавлено объяснить результат ' – Paludis

ответ

0

Вы столкнулись с проблемой обработки исходящих сообщений по-разному для входящих сообщений (в основном проблема нормализации), так что вы не можете использовать индекс по имени пользователя непосредственно, который вероятно, ваша самая значительная ценность.

Если у вас нет их пока, создать индексы ofMessageArchive(fromJID, messageType, sentDate) и ofMessageArchive(toJID, messageType, sentDate) (возможно, в другом порядке, в зависимости от того, сколько различных значений у вас есть для каждого из этих столбцов и какие другие querys вы используете, но начните с этот заказ).

Для использования этих индексов, используйте union:

select * from  
((SELECT `ofMessageArchive`.* 
    FROM `ofMessageArchive` 
    WHERE (ofMessageArchive.fromJID = '[email protected]') 
    AND `ofMessageArchive`.`messageType` IN ('Message') 
    AND (ofMessageArchive.sentDate > '1462235333109') 
    ORDER BY ofMessageArchive.sentDate ASC LIMIT 50 
) union 
    (SELECT `ofMessageArchive`.* 
    FROM `ofMessageArchive` 
    WHERE (ofMessageArchive.toJID = '[email protected]') 
    AND `ofMessageArchive`.`messageType` IN ('Message') 
    AND (ofMessageArchive.sentDate > '1462235333109') 
    ORDER BY ofMessageArchive.sentDate ASC LIMIT 50 
) 
) s 
order by s.sentDate ASC LIMIT 50 
Смежные вопросы