2016-05-18 3 views
1

ЦЕЛЬ: нужен запрос для подсчета всех «отличных» отведений за пределами текущей компании, которых нет в текущей компании. Запрос должен составлять миллионы записей между несколькими таблицами (lead_details, домены, компании)Оптимизация запроса MySQL имеет миллионы записей

EXAMPLE: 
    company 1 -> domain 1 -> lead 1 lead_details records exists. 
    company 2 -> domain 2 -> lead 1 lead_details records exists. 
    company 2 -> domain 2 -> lead 2 lead_details records exists. 
    company 3 -> domain 3 -> lead 2 lead_details records exists. 
    company 3 -> domain 3 -> lead 3 lead_details records exists. 

РЕЗУЛЬТАТ: Если я выполнить запрос для данных выше на компании 1, результат должен быть счетчик (2), так как свинец 2 & ведут 3 является уникальным и не существует в компании 1

domain_id domain_name company_id company_name lead_id lead_count 
    "2"   "D2"  "2"  "C2"  "2"  "2" 
    "3"   "D3"  "3"  "C3"  "3"  "1" 

Вот мой запрос, пожалуйста, дайте мне знать, если кто имеет какие-либо лучшее предложение.

SELECT al.* 
FROM (
    SELECT 
    d.id AS domain_id, 
    d.name AS domain_name, 
    c.id AS company_id, 
    c.name AS company_name, 
    ld.lead_id, 
    count(ld.lead_id) as lead_count 
    FROM domains d 
    INNER JOIN company c 
    ON (c.id = d.company_id AND c.id != 1) 
    INNER JOIN lead_details ld 
    ON (ld.domain_id = d.id) 
    GROUP BY ld.lead_id 
) al 
LEFT JOIN (
    SELECT ld.lead_id FROM domains d 
    INNER JOIN company c 
    ON (c.id = d.company_id AND c.id = 1) 
    INNER JOIN lead_details ld 
    ON (ld.domain_id = d.id) 
) ccl 
ON al.lead_id = ccl.lead_id 
WHERE ccl.lead_id IS NULL; 

У меня есть почти миллион строк, поэтому необходимо выяснить, лучшее решение ..

+0

Пожалуйста, добавьте вывод 'SHOW CREATE TABLE domains' к вашему вопросу, и то же самое для таблиц' company' и 'lead_details'. Это позволит нам видеть существующие индексы, а также проверять типы данных. –

ответ

0

План А

Узор

FROM (SELECT ...) 
JOIN (SELECT ...) ON ... 

является неэффективным, особенно в старых версиях MySQL. Это связано с тем, что ни один из подзапросов не имеет индексов, поэтому (в более старых версиях) для одного из подзапросов требуется повторное полное сканирование таблицы.

Чем лучше метод, чтобы попытаться переформулировать в

FROM t1 ... 
JOIN t2 ... ON ... 
JOIN t3 ... ON ... 
LEFT JOIN t4 ... ON ... 
LEFT JOIN t5 ... ON ... 

Plan B

Это ближе к тому, что у вас есть ...

CREATE TEMPORARY TABLE ccl 
     (INDEX(lead_id)) 
    SELECT ... -- the stuff that is after LEFT JOIN 

Затем замените этот подзапрос с только ccl. Это обеспечивает индекс, отсутствующий в исходном запросе.

План C

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

Смежные вопросы