2013-12-17 6 views
0

Привет всем чемпионам тамУлучшение производительности MySQL запросов

Я далек от гуру, когда речь идет о запросах высокой производительности SQL и подивитесь в тех, кто может помочь мне улучшить запрос ниже. Он работает, но занимает слишком много времени, тем более, что я могу иметь около 100 записей в части IN().

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

SELECT inv.amount 
FROM invoice inv 
WHERE inv.invoiceID IN (
     SELECT childInvoiceID 
     FROM invoiceRelation ir 
       LEFT JOIN Payment pay ON pay.invoiceID = ir.parentInvoiceID 
     WHERE pay.paymentID IN (125886, 119293, 123497)) 
+0

Имеются ли в ваших таблицах индексы столбцов в частях запроса WHERE? – Jakob

+0

Это внутреннее соединение – Strawberry

ответ

3

Восстановите свой запрос, чтобы использовать соединение вместо подзапроса. Кроме того, используйте INNER JOIN вместо LEFT JOIN в таблице Payment. Это оправдано, поскольку у вас есть фильтр WHERE, который в любом случае будет фильтровать строки без соответствия в таблице «Платежи».

SELECT inv.amount 
FROM invoice inv 
INNER JOIN invoiceRelation ir ON inv.incoiceID = ir.childInvoiceID 
INNER JOIN Payment pay on pay.invoiceID = ir.parentInvoiceID 
WHERE pay.paymentID IN (...) 
+0

Ничего себе, какая разница. От 380 мс до 0,4 мс. Спасибо также за разъяснение вашего решения, помогает мне понять. Спасибо, Дэн. –

0

Я думаю, вместо первого in вы можете использовать внутреннее соединение.

select inv.amount from invoice inv 
inner join invoiceRelation ir on (inv.invoiceID = ir.childInvoiceID) 
LEFT JOIN Payment pay ON pay.invoiceID = ir.parentInvoiceID 
WHERE pay.paymentID IN (125886,119293,123497) 
2

Одним из способов повышения производительности является наличие хорошего индекса в соответствующих столбцах. В вашем примере индекс на inv.invoiceI D скорее всего ускорит запрос.

Также на pay.paymentID

Попробуйте это и посмотреть, если это помогает:

ALTER TABLE invoice ADD INDEX invoiceID_idx (invoiceID); 

и

ALTER TABLE Payment ADD INDEX paymendID_idx (paymentID); 
+0

+1 В большинстве случаев индексы являются наиболее важными для повышения эффективности выбора. –

+0

Yup У меня были индексы, но я предполагаю, что мой запрос не использовал их из-за огромного предложения where. Теперь они работают :-) Спасибо Якоб. –

0

Что делать, если вы пытаетесь как это вместо:

SELECT inv.amount 
FROM invoice inv 
inner join invoiceRelation ir on inv.invoiceID = ir.parentInvoiceID 
left join Payment pay on pay.invoiceID = ir.parentInvoiceID 
WHERE pay.paymentID IN (125886, 119293, 123497) 

(OR) bette р; если вы уверены, что у вас есть счет-фактура FK в таблице платежей, сделайте это left join до inner join.

Вкратце, вы должны всегда избегать коррелированного подзапроса, если вы можете заменить этот подзапрос на соединение.

+0

в любом случае, это внутреннее соединение – Strawberry

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