2017-02-15 3 views
0

Вот три таблицы, заказ, order_record, pay, с почти 2300000 записями.mysql «отдельный запрос» из таблицы 3 выполняет медленные операции при больших данных

будет больше чем 1 запись в таблице выплат, давая 1 ORDER_ID, так что мне нужно использовать DISTINCT для удаления Повторного результата

теперь мне нужно, чтобы получить различные данные из этих трех соединения таблиц на order_id, пример запрос sql ниже:

SELECT 
    DISTINCT (a.order_id) 
    a.order_id,a.user_id 
    b.boss_order_id, 
    c.pay_id, 

    FROM order a 
    LEFT JOIN order_record b ON a.order_id = b.order_id AND b.is_delete IN (0,1) 
    LEFT JOIN pay c ON a.order_id = c.order_id AND c.is_delete =0 WHERE 1=1 AND a.is_delete IN (0,1) 
    ORDER BY a.id DESC LIMIT 0, 10 

Этот запрос займет много времени. потом изменить, чтобы использовать "GROUP BY":

SELECT 

    a.order_id,a.user_id 
    b.boss_order_id, 
    c.pay_id, 

    FROM order a 
    LEFT JOIN order_record b ON a.order_id = b.order_id AND b.is_delete IN (0,1) 
    LEFT JOIN pay c ON a.order_id = c.order_id AND c.is_delete =0 WHERE 1=1 AND a.is_delete IN (0,1) 
    GROUP BY a.order_id 
    ORDER BY a.id DESC LIMIT 0, 10 

на этот раз запрос занимает 122 секунд.

Есть ли более быстрый способ реализовать?

+0

Вы указали индексирование столбцов? – FreedomPride

+0

Пожалуйста, добавьте структуру ваших таблиц (с индексами), а также поясницу объяснения ваших запросов. –

+0

Второй запрос недействителен, поскольку вы выбираете неагрегатные столбцы. И 'DISTINCT' часто использует' GROUP BY' в качестве реализации, поэтому они должны вести себя аналогичным образом. Вышеупомянутый комментарий об индексировании имеет значение. –

ответ

0

Вы используете left join. Таким образом, вы можете сделать:

SELECT o.order_id, o.user_id, orr.boss_order_id, p.pay_id, 
FROM (SELECT o.* 
     FROM order o 
     WHERE o.is_delete IN (0, 1) 
     ORDER BY o.id DESC 
     LIMIT 10 
    ) o LEFT JOIN 
    order_record orr 
    ON o.order_id = orr.order_id AND 
     orr.is_delete IN (0, 1) LEFT JOIN 
    pay p 
    ON o.order_id = p.order_id AND 
     p.is_delete = 0 
WHERE 1=1 AND o.is_delete IN (0, 1) 
GROUP BY o.order_id 
ORDER BY o.id DESC 
LIMIT 0, 10 

Вы используете GROUP BY неправильно, потому что у вас есть неагрегированные столбцы в SELECT, которые не в GROUP BY.

+0

thx много! Он работает, я получил ключ от вашего ответа: получите лимитные записи числа в порядке таблицы, затем присоедините запрос к таблице order_record и оплатите, что я действительно присоединил к запросу, прежде чем заказывать и ограничивать результат. – halfdark

+0

Вот еще вопрос, что, если я хочу добавить 'orr.boss_order_id> 'xxxx'' до' limit 10'? – halfdark

+0

@halfdark. , , Добавьте его во второе предложение 'on', где' orr' уже имеет условия. –

0

Другой подход пусть где предложение сделать большую работу:

select ... 
from order 
left join order_using using (order_id) 
... 
where 
order.order_id < (select max(order_id) from orders order by order_id limit 10) ... 
limit 10 

Конечный предел 10 странно, хотя, как вы можете получить частичные записи из заказа, если вы уронили группу по. То есть вы, вероятно, захотите его сбросить и просто установите таблицу лимитных ордеров. С помощью группы вы будете получать случайные данные из таблицы b и c, если вы не используете агрегированную функцию, чтобы сообщить mysql, какие значения строк вы хотите.