2015-06-04 4 views
0

Прежде всего, например, у меня есть 3 таблицы A, B, C. Таблица A имеет отношение к таблице B, а таблица имеет отношение к таблице C. Я хочу получить SUM некоторого поля из таблицы A, которая зависит на некоторых полей из таблицы C.MySql странная производительность

Таблица А имеет> 300 тыс строк, таблица B имеет> 4k строк таблицы с имеет ~ 100 строк

Мой запрос выглядит следующим образом: выполнение

SELECT SUM(a.hours) AS total 
FROM table_a a 
LEFT JOIN table_b b 
    ON a.table_b_id = b.id 
LEFT JOIN table_c c 
    ON b.table_c_id = c.id 
WHERE a.customer_id = 1 
    AND c.title IN ('Title D','Title E') 

запросов время ~ 7 секунд, это очень медленно. Но время выполнения запроса, как показано ниже, составляет ~ 0,0 сек.

SELECT a.hours 
FROM table_a a 
LEFT JOIN table_b b 
    ON a.table_b_id = b.id 
LEFT JOIN table_c c 
    ON b.table_c_id = c.id 
WHERE a.customer_id = 1 
    AND c.title IN ('Title D','Title E') 

Почему СУМ так медленно? что мне делать?

+2

У вас есть указатель на заголовок в таблице C? – MartianCodeHound

+0

Ваш первый запрос на самом деле такой же, как с использованием INNER JOINs, а MySQL довольно глупо в оптимизации бесполезных внешних соединений. И второй запрос может быть таким же, как и никакое соединение вообще, если есть правильные отношения PK-FK (и, возможно, MySQL может устранить ненужные объединения, но я так не думаю) – dnoeth

+0

Почему это связано с mongodb и postgresql? –

ответ

1

Переместите условие ON пункта для соответствующей таблицы:

SELECT SUM(a.hours) AS total 
FROM table_a a 
LEFT JOIN table_b b 
    ON a.table_b_id = b.id 
LEFT JOIN table_c c 
    ON b.table_c_id = c.id 
    AND c.title IN ('Title D','Title E') 
WHERE a.customer_id = 1 

EDIT 1 Согласно @dnoeth комментарий Я могу согласиться, вероятно, мы должны использовать inner join когда присоединиться table_c:

SELECT SUM(a.hours) AS total 
FROM table_a a 
LEFT JOIN table_b b 
    ON a.table_b_id = b.id 
INNER JOIN table_c c 
    ON b.table_c_id = c.id 
    AND c.title IN ('Title D','Title E') 
WHERE a.customer_id = 1 
+0

Хорошо, теперь его около ~ 1 сек. Нравится. – user3234484

+1

@ user3234484: Это быстро, но это не тот же результат, что и ваш первый запрос :-) – dnoeth

+1

oops ... может быть, вы правы ... мы должны использовать 'inner join' при присоединении' table_c' – Alex

0

Использовать LEFT JOIN в обоих местах и ​​добавить этот составной индекс:

INDEX(customer_id, title) 
Смежные вопросы