2016-10-27 4 views
1

Я работаю над запросом, которому необходимо подключить 4 больших стола.MySQL, как я могу сделать этот запрос быстрее?

Таблицы:

Table_1 (ID, активный, price1, price2, имя, категория1, категория2) Это главная таблица, которая имеет все продукты, 32561 строк

table_2 (ID, table_1_ID, room, stock) Это таблица, содержащая запас продуктов в таблице_1, эта таблица может иметь table_1.ID несколько раз, 190400 строк

table_3 (ID, table_1_ID, изображения) Эта таблица содержит больше информации о продукте, как образы, некоторые продукты не имеют их, 6546 строк

table_4 (table_1_ID, вид, тип) Эта таблица содержит вид продукции (просмотров в месяц)

что я хочу:

Я пытаюсь сделать запрос, который отображает 20 из наиболее популярных и продуктов.

Условия:

  1. Это может отображать только продукты, которые находятся в table_1.category1 (А, В, С, D, Е)
  2. Это может отображать только продукты, которые активны = 'T "
  3. Он может отображать только те продукты, которые находятся в комнате LJ0001 и MS0001
  4. Он может отображать только продукты, которые имеют по крайней мере один запас

Код:

SELECT DISTINCT(Table_1.ID), Table_1.price1, Table_1.price2 
    , Table_1.name, Table_1.category2, Table_3.images 
FROM Table_1 
    LEFT JOIN Table_2 ON Table_1.ID=Table_2.table_1_ID 
    LEFT JOIN table_3 ON table_1.ID=table_3.table_1_ID 
    LEFT JOIN table_4 ON table_1.ID=table_4.table_1_ID 
WHERE Table_1.active='T' 
    AND (Table_1.category1 LIKE 'A%' 
     OR Table_1.category1 LIKE 'B%' 
     OR Table_1.category1 LIKE 'C%' 
     OR Table_1.category1 LIKE 'D%' 
     OR Table_1.category1 LIKE 'E%' 
     ) 
    AND table_2.room IN ('LJ0001','MS0001') 
    AND table_2.stock!=0 
ORDER BY table_4.view DESC, Table_1.name 
LIMIT 10 OFFSET 0 

Примечание:

Код выше работ. Но это займет некоторое время. Я ищу любые исправления, которые могли бы сделать это быстрее.

Любая помощь будет приятной! Спасибо заранее.

EXPLAIN EXTENDED

Link to image

+0

Какие индексы у вас есть на разных таблицах? Индекс имеет большое значение в отношении этого. Вы используете внешние ключи? – h2ooooooo

+0

Начните с отображения индексов на каждой таблице, а не только столбцов; а затем выполните EXPLAIN запроса и покажите результаты этого, чтобы увидеть, какие индексы используют запрос. –

+0

Возможно, вам потребуется добавить некоторые индексы. Используйте 'explain extended' с последним запросом, чтобы выяснить, что лучше всего индексировать. – aynber

ответ

1

Используйте обновленный запрос ниже:

EXPLAIN EXTENDED 
SELECT Table_1.ID, Table_1.price1, Table_1.price2 
, Table_1.name, Table_1.category2, Table_3.images 
FROM Table_1 
LEFT JOIN Table_2 ON Table_1.ID=Table_2.table_1_ID 
LEFT JOIN table_3 ON table_1.ID=table_3.table_1_ID 
LEFT JOIN table_4 ON table_1.ID=table_4.table_1_ID 
WHERE Table_1.active='T' 
AND (Table_1.category1 = 'A' 
    OR Table_1.category1 = 'B' 
    OR Table_1.category1 = 'C' 
    OR Table_1.category1 = 'D' 
    OR Table_1.category1 = 'E' 
    ) 
AND table_2.room IN ('LJ0001','MS0001') 
AND table_2.stock != 0 
ORDER BY table_4.view DESC, Table_1.name 
LIMIT 10 OFFSET 0 

Я удалил DISTINCT, потому что я предполагал, что table_1.ID является первичным ключом. Если это так, нет необходимости использовать DISTINCT с первичными ключами, потому что он уже отличается. Я также изменил оператор LIKE на =, потому что он работает быстрее.

Тогда вам нужно убедиться, что все поля объединения, такие как table_1_ID, были проиндексированы.

И вы можете заметить EXPLAIN EXTENDED на верхней части запроса - с помощью этой статьи вы получите что-то вроде этого из БД:

  id: 1 
      select_type: PRIMARY 
      table: t1 
      type: index 
      possible_keys: NULL 
      key: PRIMARY 
      key_len: 4 
      ref: NULL 
      rows: 4 
      filtered: 100.00 
      Extra: Using index 

Вы получите описание для каждой таблицы. Все внешние ключи, используемые в запросе, будут перечислены, включая данные, например, если у иностранного ключа есть индекс и т. Д. Вы найдете дополнительную информацию here.

+0

Я проверю индексы, если есть проблема. Я думаю, что в table_4 есть некоторые проблемы. Мне нужна часть LIKE, потому что table_1.category1 выглядит так: (A.01.001, A.01.002, A.01.003 ....) –

+0

Я предлагаю сделать таблицу 'categories' и использовать' category_id' вместо что – Roman

+0

К сожалению, я не могу. Таблицы (table_1 и table_2) заданы программой компании, и я должен использовать то, что у меня есть ... –

0

Я думаю, что мои исправления могут вам помочь. если вы можете установить sql_cache_type = 2 в my.cnf, вы должны использовать SQL_CACHE в запросе (если нет полей с типом текста), и лучше сначала сделать условия, которые «проще» для БД (LIKE с OR очень медленны), если вы используете INNODB, вы можете установить больший буферный пул для MySQL

SELECT SQL_CACHE DISTINCT(Table_1.ID), Table_1.price1, Table_1.price2 
, Table_1.name, Table_1.category2, Table_3.images 
FROM Table_1 
LEFT JOIN Table_2 ON Table_1.ID=Table_2.table_1_ID 
LEFT JOIN table_3 ON table_1.ID=table_3.table_1_ID 
LEFT JOIN table_4 ON table_1.ID=table_4.table_1_ID 
WHERE Table_1.active='T' 
AND table_2.stock!=0 
AND table_2.room IN ('LJ0001','MS0001') 
AND (Table_1.category1 LIKE 'A%' 
    OR Table_1.category1 LIKE 'B%' 
    OR Table_1.category1 LIKE 'C%' 
    OR Table_1.category1 LIKE 'D%' 
    OR Table_1.category1 LIKE 'E%' 
    ) 
ORDER BY table_4.view DESC, Table_1.name 
LIMIT 10 OFFSET 0 
+0

Хорошо, изменение условий помогло немного ускорить процесс доставки! –

+0

@ MarkoMihalič проверить кеширование, если вы можете использовать его – marcus

+0

Я использую его, и он отлично работает –

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