2013-04-16 2 views
0

Учитывая SQL занимает 1.2s:SQL оптимизация - медленный запрос

SELECT DISTINCT contracts.id, jt0.id, jt1.id, jt2.id, jt3.id FROM contracts 
LEFT JOIN accounts jt0 ON jt0.id = contracts.account_id AND jt0.deleted=0 
LEFT JOIN manufacturers jt1 ON jt1.id = contracts.manufacturer_id AND jt1.deleted=0 
LEFT JOIN products jt2 ON jt2.id = contracts.product_id AND jt2.deleted=0 
LEFT JOIN users jt3 ON jt3.id = contracts.assigned_user_id AND jt3.deleted=0 
WHERE contracts.deleted=0 
ORDER BY contracts.application_number ASC 
LIMIT 0,21 

вот что объяснить протяженные возвращаются:

id select_type table type possible_keys key key_len ref rows 
1 SIMPLE contracts ref idx_contracts_deleted idx_contracts_deleted 2 const 18968 100.00 Using where; Using temporary; Using filesort 
1 SIMPLE jt0 eq_ref PRIMARY,idx_accnt_id_del,idx_accnt_assigned_del PRIMARY 108 xxx.contracts.account_id 1 100.00 
1 SIMPLE jt1 eq_ref PRIMARY,idx_manufacturers_id_deleted,idx_manufacturers_deleted PRIMARY 108 xxx.contracts.manufacturer_id 1 100.00 
1 SIMPLE jt2 eq_ref PRIMARY,idx_products_id_deleted,idx_products_deleted PRIMARY 108 xxx.contracts.product_id 1 100.00 
1 SIMPLE jt3 eq_ref PRIMARY,idx_users_id_del,idx_users_id_deleted,idx_users_deleted PRIMARY 108 xxx.contracts.assigned_user_id 1 100.00 

мне нужно отчетливый, мне нужно все стыки, чтобы остаться, я нужен заказ, и мне нужен лимит.
Могу ли я как-то его оптимизировать?

+0

Является ли это заметно быстрее без DISTINCT или ORDER BY? –

+0

занимает 0.078 без заказа и 0,156 без ограничений –

+0

что плохого в 1.2s в любом случае? как часто вы его запускаете? – Aprillion

ответ

0

Это единственные предложения я уже получил

  1. Я надеюсь, что идентификаторы определены в качестве первичных ключей и внешних ключей с отношением между таблицами.

  2. Может application_number может быть проиндексирован (то вроде будет быстрее)

  3. Может быть, если вы используете MyISAM, то SQL может быть быстрее, если вы блокируете таблицы перед выбором (не забудьте разблокировка впоследствии)

+0

Да, ключи четко определены. Да, у меня есть указатель на application_number. Я использую MyIsam - я проверю, поможет ли блокировка. –

0

Сначала создайте необходимый индекс в следующих столбцах.

contracts.application_number, manufacturers.deleted, products.deleted, users.deleted

SELECT DISTINCT contracts.id, jt0.id, jt1.id, jt2.id, jt3.id 
FROM contracts 
LEFT JOIN accounts jt0 
ON contracts.deleted=0 AND jt0.id = contracts.account_id 
LEFT JOIN manufacturers jt1 
ON jt1.deleted=0 AND jt1.id = contracts.manufacturer_id 
LEFT JOIN products jt2 
ON jt2.deleted=0 AND jt2.id = contracts.product_id 
LEFT JOIN users jt3 
ON jt3.deleted=0 AND jt3.id = contracts.assigned_user_id 
ORDER BY contracts.application_number ASC 
LIMIT 0,21 

Как вы уже упоминали вы уже индекс по contracts.deleted

FROM 
    (SELECT * FROM contracts WHERE contracts.deleted = 0 USE INDEX(<deletedIndexName>)) 
LEFT JOIN 
    accounts jt0 
ON 
    jt0.id = contracts.account_id 
LEFT JOIN 
    ... 
+0

У меня есть все индексы на месте уже –

+0

Вы пробовали с этим запросом? – Meherzad

+0

попробуйте создать составной индекс в следующих столбцах в таблице контрактов (account_id, manufacturer_id, product_id, assign_user_id) – Meherzad

0

Try изменения индексов на вспомогательных таблицах для включения в колонку deleted:

  • accounts(id, deleted)
  • manufacturers(id, deleted)
  • products(id, deleted)
  • users(id, deleted)

Включая все столбцы в индексе, MySQL имеет возможность лучше воспользоваться индексом.

Еще одно предложение - выяснить, что вызывает дублирование значений, и использовать подзапросы для устранения дубликатов, а не distinct.

Например, с указанными выше показателями:

from contracts c left join 
    (select id 
     from accounts 
     where deleted = 0 
     group by id 
    ) a 
    on c.account_id = a.id 
    . . . 

подзапрос должен использовать только индекс, который может ускорить процесс.

+0

У меня уже есть указатели, которые вы упомянули. Я не могу легко избавиться от отдельных и заменить его подзапросами из-за механики за приложением, в котором я использую SQL. –

0

Попробуйте немного ссылочной целостности? Уверен, что запрос выполняется намного быстрее с внутренними соединениями. Это должно быть, потому что оптимизатор запросов имеет больше возможностей для работы. Вы платите по цене select, не заботясь о том, чтобы не заботиться об этом create.

Я бы также удалил удаленные строки в свои собственные таблицы и ударил столбцы deleted.Ваши запросы будут проще и, скорее всего, будут работать быстрее.

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