2011-01-26 2 views
0

У меня возникли проблемы с использованием производной таблицы в MySQL. Использует ли производная таблица по сути замедляет обработку запроса?Проблемы производительности с производной таблицей в SQL

Вот запрос, который я пытаюсь запустить. Он не будет выполняться и просто истекает.

Это действительно так. Действительно, я выделил проблему для последнего соединения. Когда я вынимаю последнее соединение, он отлично работает. Но когда я добавляю последнее соединение обратно, он отказывается выполнять.

SELECT cr.COMMUNICATIONS_ID AS ANSWER_ID, 
     cr.CONSUMER_ID as VIEWER_ID, 
     cr.ACTION_LOG_ID, 
     nc.PARENT_COMMUNICATIONS_ID AS QUESTION_ID, 
     nc.SENDER_CONSUMER_ID AS REPLIER_ID, 
     ces.EXPERT_SCORE AS REPLIER_EXPERTISE, 
     cim.CONSUMER_INTEREST_EXPERT_ID AS DOMAIN 
    FROM (SELECT 234 AS CONSUMER_ID, 
    ACTION_LOG_ID, 
    COMMUNICATIONS_ID 
    FROM consumer_action_log 
    WHERE COMM_TYPE_ID=4) AS cr 
JOIN network_communications AS nc ON 
cr.COMMUNICATIONS_ID=nc.COMMUNICATIONS_ID 
JOIN communication_interest_mapping AS cim ON 
nc.PARENT_COMMUNICATIONS_ID=cim.COMMUNICATION_ID 
JOIN consumer_expert_score AS ces ON 
nc.SENDER_CONSUMER_ID=ces.CONSUMER_ID 
     AND cim.CONSUMER_INTEREST_EXPERT_ID=ces.CONSUMER_EXPERT_ID; 
+0

Что происходит, когда вы запускаете этот подзапрос самостоятельно? Успешно ли это? Я бы сделал объяснение по подзапросу сам по себе, а затем еще один по запросу в целом. – TehShrike

+0

Он преуспевает. Действительно, я выделил проблему для последнего соединения. Когда я вынимаю последнее соединение, он отлично работает. Но когда я добавляю последнее соединение обратно, он отказывается выполнять. – Spencer

+1

Каковы результаты EXPLAIN по этому запросу? У вас есть указатель на consumer_id/expert_id в каждой таблице? Я бы рекомендовал индекс, охватывающий оба столбца в каждой таблице. – TehShrike

ответ

2

Надеюсь, это поможет ... Вот несколько операторов mysql CREATE INDEX. В принципе, если вы можете добавить индексы, убедитесь, что есть индекс, который охватывает каждый из ваших столбцов, которые соединяют две или более таблицы.

CREATE INDEX idx_nc 
ON network_communications(COMMUNICATIONS_ID); 

CREATE INDEX idx_cim 
ON communication_interest_mapping(COMMUNICATION_ID); 

CREATE INDEX idx_ces 
ON consumer_expert_score(CONSUMER_ID, CONSUMER_EXPERT_ID); 

Производные таблицы не являются по своей сути плохо, но в этом случае (см ниже), вы тянете все записи из consumer_action_log, которые имеют comm_type_id из 4. Там, кажется, не быть связь назад другие таблицы. Это может быть причиной того, что sql никогда не возвращается.

SELECT cr.COMMUNICATIONS_ID, 
      cr.CONSUMER_ID, 
      cr.ACTION_LOG_ID, 
      nc.PARENT_COMMUNICATIONS_ID, 
      nc.SENDER_CONSUMER_ID, 
      ces.EXPERT_SCORE, 
      cim.CONSUMER_INTEREST_EXPERT_ID 

    FROM (SELECT 234 AS CONSUMER_ID, 
      ACTION_LOG_ID, 
      COMMUNICATIONS_ID 
      FROM consumer_action_log 
      WHERE COMM_TYPE_ID=4) AS cr 

JOIN network_communications AS nc ON 
     cr.COMMUNICATIONS_ID=nc.COMMUNICATIONS_ID 

JOIN communication_interest_mapping AS cim ON 
     nc.PARENT_COMMUNICATIONS_ID=cim.COMMUNICATION_ID 

JOIN consumer_expert_score AS ces ON 
     nc.SENDER_CONSUMER_ID=ces.CONSUMER_ID 
     AND cim.CONSUMER_INTEREST_EXPERT_ID=ces.CONSUMER_EXPERT_ID; 
1

Помимо индексов, которые должны существовать в ваших справочных таблиц, как указано в Anser Джоном, я бы обеспечить вам индекс COMM_TYPE_ID в вашем consumer_action_log столе тоже.

Затем добавьте одно ключевое слово в предложение ... Я всегда видел отличные результаты при выполнении запроса хорошо организован вместо того, чтобы полагаться на двигатель запроса к optimze ... see another sample here

SELECT STRAIGHT_JOIN 
     cr.COMMUNICATIONS_ID AS ANSWER_ID, 
     cr.CONSUMER_ID as VIEWER_ID, 
     etc... rest of your query... 

Это может оптимизатор пытается посмотреть на другие таблицы, чтобы выяснить, что нужно получить. См. Комментарии в другом ответе StackOverflow, на который я предоставил ссылку.