MySql сложная проблема производительности соединения

Пожалуйста, рассмотрите следующий запрос

SELECT * FROM PC_SMS_OUTBOUND_MESSAGE AS OM  
JOIN MM_TEXTOUT_SERVICE AS TOS ON TOS.TEXTOUT_SERVICE_ID = OM.SERVICE_ID  
JOIN PC_SERVICE_NUMBER AS SN ON OM.TO_SERVICE_NUMBER_ID = SN.SERVICE_NUMBER_ID       
JOIN PC_SUBSCRIBER AS SUB ON SUB.SERVICE_NUMBER_ID = SN.SERVICE_NUMBER_ID  
JOIN MM_CONTACT CON ON CON.SUBSCRIBER_ID = SUB.SUBSCRIBER_ID 

--AND CON.MM_CLIENT_ID = 1

AND OM.CLIENT_ID= 1 
AND OM.CREATED>='2013-05-08 11:47:53' AND OM.CREATED<='2014-05-08 11:47:53'  
ORDER BY OM.SMS_OUTBOUND_MESSAGE_ID DESC LIMIT 50

Чтобы получить набор данных, который мне требуется, мне нужно отфильтровать (закомментированные) CONTACTS client_id, а также OUTBOUND_MESSAGES client_id, но это то, что меняет производительность с миллисекунд до десятков минут.

План выполнения без "AND CON.MM_CLIENT_ID = 1":

id  select_type table   type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  OM  index   FK4E518EAA19F2EA2B,SERVICEID_IDX,CREATED_IDX,CLIENTID_IDX,CL_CR_ST_IDX,CL_CR_STYPE_ST_IDX,SID_TOSN_CL_CREATED_IDX   PRIMARY 8   NULL    6741    3732.00 Using where
1   SIMPLE  SUB ref PRIMARY,FKA1845E3459A7AEF   FKA1845E3459A7AEF   9   mmlive.OM.TO_SERVICE_NUMBER_ID  1   100.00  Using where
1   SIMPLE  SN  eq_ref  PRIMARY PRIMARY 8   mmlive.OM.TO_SERVICE_NUMBER_ID  1   100.00  Using where
1   SIMPLE  CON ref FK2BEC061CA525D30,SUB_CL_IDX    FK2BEC061CA525D30   8   mmlive.SUB.SUBSCRIBER_ID    1   100.00  
1   SIMPLE  TOS eq_ref  PRIMARY,FKDB3DF298AB3EF4E2  PRIMARY 8   mmlive.OM.SERVICE_ID    1   100.00  

План выполнения с "AND CON.MM_CLIENT_ID = 1":

id  select_type table   type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  CON ref FK2BEC061CA525D30,FK2BEC06134399E2A,SUB_CL_IDX  FK2BEC06134399E2A   8   const   18306   100.00  Using temporary; Using filesort
1   SIMPLE  SUB eq_ref  PRIMARY,FKA1845E3459A7AEF   PRIMARY 8   mmlive.CON.SUBSCRIBER_ID    1   100.00  
1   SIMPLE  OM  ref FK4E518EAA19F2EA2B,SERVICEID_IDX,CREATED_IDX,CLIENTID_IDX,CL_CR_ST_IDX,CL_CR_STYPE_ST_IDX,SID_TOSN_CL_CREATED_IDX   FK4E518EAA19F2EA2B  9   mmlive.SUB.SERVICE_NUMBER_ID    3   100.00  Using where
1   SIMPLE  SN  eq_ref  PRIMARY PRIMARY 8   mmlive.SUB.SERVICE_NUMBER_ID    1   100.00  Using where
1   SIMPLE  TOS eq_ref  PRIMARY,FKDB3DF298AB3EF4E2  PRIMARY 8   mmlive.OM.SERVICE_ID    1   100.00  

Любые предложения о том, как отформатировать вышеупомянутое, чтобы сделать его немного проще для глаз, были бы хорошими.

Поля ID являются первичными ключами. Есть индексы на всех соединяющихся столбцах.

2 ответа

Решение

Я разгадал загадку! В любом случае, так что я поделюсь.

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

 "Using temporary; Using filesort"

Просто добавив ключевое слово STRAIGHT_JOIN непосредственно после выбора, я мог принудительно объединить план выполнения в порядке, указанном непосредственно в запросе. Рад, что кто-то, обладающий более глубокими знаниями в этой области, может противоречить любому из вышеперечисленного с точки зрения того, что на самом деле происходит, но это определенно работает.

Вы можете решить эту проблему, используя подзапрос:

JOIN (SELECT C.* FROM CONTACTS C WHERE C.USER_ID = 1) ON C.SUBSCRIBER_ID = SUB.ID

Это материализует совпадающие строки, что может оказать влияние на план запроса.

Если это не работает, отредактируйте ваш запрос и добавьте:

  • explain планы на оба запроса.
  • Индексы доступны по таблице.

РЕДАКТИРОВАТЬ:

Можете ли вы попробовать создать составной индекс:

PC_SMS_OUTBOUND_MESSAGE(CLIENT_ID, CREATED, SERVICE_ID, TO_ SERVICE_ID, SMS_OUTBOUND_MESSAGE_ID);

Это может изменить оба плана запроса для запуска на OM таблица с соответствующей фильтрацией, надеюсь, сделав результаты стабильными и хорошими.

Другие вопросы по тегам