2013-03-19 5 views
1

Привет, я пытаюсь запустить этот оператор select, используя этот запрос, и он занимает 2 часа для запуска. Я настроил весь индекс, чтобы быть правильным. Но это все еще занимает навсегда, есть ли что-то, чего я не вижу, или более эффективный способ объединения таблиц вместе, что ускорит этот запрос?Mysql Присоединиться к оптимизации запросов

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

SELECT 
    p.sap_article_id, 
    p.numeric_line_code, 
    p.uag_linecode, 
    p.uag_partnum, 
    p.part_description, 
    p.jobber_price, 
    p.jobber_core, 
    p.discount1, 
    p.discount2, 
    p.uom, 
    p.product_category, 
    w.as400_warehouse, 
    w.atp_qty, 
    p.updated, 
    t.regular_discount  
FROM part p 
     LEFT JOIN tabjbmaw t ON t.accountnum  = '73050' 
          AND p.numeric_line_code = t.numeric_line_code 
          AND p.sub_code   = t.sub_code  
     JOIN warehouse w ON w.sap_article_id = p.sap_article_id; 

+----+-------------+-----------+------+--------------------------------------------------+-----------------------+---------+----------------------------------+--------+-------------+ 
| id | select_type | table  | type | possible_keys         | key     | key_len | ref        | rows | Extra  | 
+----+-------------+-----------+------+--------------------------------------------------+-----------------------+---------+----------------------------------+--------+-------------+ 
| 1 | SIMPLE  | part  | ALL | PRIMARY,sap_article,part_sap_article_id_fk  | NULL     | NULL | NULL        | 389309 |    | 
| 1 | SIMPLE  | warehouse | ref | article           | article    | 130  | inventory.part.sap_article_id |  5 | Using where | 
| 1 | SIMPLE  | tabjbmaw | ref | numeric_line_code_idx,subcode_idx,accountnum_idx | numeric_line_code_idx | 5  | inventory.part.numeric_line_code |  19 |    | 
+----+-------------+-----------+------+--------------------------------------------------+-----------------------+---------+----------------------------------+--------+-------------+ 

Спасибо за вашу помощь

+-----------------------------+--------------+------+-----+---------------------+-----------------------------+ 
| Field      | Type   | Null | Key | Default    | Extra      | 
+-----------------------------+--------------+------+-----+---------------------+-----------------------------+ 
| sap_article_id    | varchar(24) | NO | PRI |      |        | 
| sap_brand_id    | varchar(20) | NO |  | NULL    |        | 
| uag_partnum     | varchar(20) | NO | MUL | NULL    |        | 
| uag_linecode    | varchar(5) | NO | MUL | NULL    |        | 
| cag_partnum     | varchar(20) | NO | MUL | NULL    |        | 
| cag_linecode    | varchar(5) | NO |  | NULL    |        | 
| product_category_legacy  | varchar(20) | NO |  | NULL    |        | 
| part_description   | varchar(128) | NO |  | NULL    |        | 
| abc_indicator    | varchar(8) | NO |  | NULL    |        | 
| pack_code     | varchar(8) | NO |  | NULL    |        | 
| case_qty     | int(11)  | NO |  | NULL    |        | 
| per_car_qty     | int(11)  | NO |  | NULL    |        | 
| uom       | varchar(6) | NO |  | NULL    |        | 
| upc_code     | varchar(128) | NO |  | NULL    |        | 
| jobber_price    | float(14,4) | YES |  | NULL    |        | 
| jobber_core     | float(14,4) | YES |  | NULL    |        | 
| date_last_price_change  | timestamp | NO |  | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | 
| weight      | float(14,4) | YES |  | NULL    |        | 
| weight_unit     | varchar(6) | NO |  | NULL    |        | 
| dimension_type    | varchar(6) | NO |  | NULL    |        | 
| length      | float(14,4) | YES |  | NULL    |        | 
| width      | float(14,4) | YES |  | NULL    |        | 
| height      | float(14,4) | YES |  | NULL    |        | 
| updated      | tinyint(1) | NO |  | 0     |        | 
| superseded_sap_article_id | varchar(24) | YES |  | NULL    |        | 
| last_updated    | timestamp | NO |  | 0000-00-00 00:00:00 |        | 
| hour_updated    | int(11)  | YES |  | NULL    |        | 
| discount1     | float  | YES |  | NULL    |        | 
| discount2     | float  | YES |  | NULL    |        | 
| product_category   | varchar(3) | YES |  | NULL    |        | 
| superseded_part_number  | varchar(20) | YES |  | NULL    |        | 
| sub_code     | varchar(3) | YES | MUL | NULL    |        | 
| date_effective_price_change | date   | YES |  | NULL    |        | 
| numeric_line_code   | varchar(3) | YES | MUL | NULL    |        | 
| list      | float  | YES |  | NULL    |        | 
+-----------------------------+--------------+------+-----+---------------------+-----------------------------+ 
+0

Каких РЕГИСТРИРУЙТЕСЬ вы хотите на складском столе? Вы пытались переместить «73050» = tabjbmaw.accountnum в предложение WHERE? – Melanie

+2

Нет, это была бы ужасная ошибка, чтобы удалить это утверждение из части LEFT JOIN. Прежде всего оптимизатор работает так же в предложениях JOIN и WHERE, а во-вторых, фильтр, вставленный в предложение WHERE, делает связанную таблицу INNER связанной, что неверно в этом случае, потому что он хочет присоединиться к OUTER. – Sebas

+0

нам нужны пустые значения обратно в скидку, так что переместить его до конца не поможет. он должен оставаться там – user1863457

ответ

1

У меня есть индексы, установленные для всех элементов соединены вместе

Да, но я угадываю из названий индексов, что каждый индекс имеет только одно поле.

Давайте рассмотрим несколько столбцов в описании.

| table  | possible_keys         | key     
+-----------+--------------------------------------------------+---------------- 
| part  | PRIMARY,sap_article,part_sap_article_id_fk  | NULL     
| warehouse | article           | article    
| tabjbmaw | numeric_line_code_idx,subcode_idx,accountnum_idx | numeric_line_code_idx 

Он может использовать индекс для numeric_line_code, субкода и AccountNum, но есть только три индекса, каждый с одним из полей, а не индекс, который имеет все поля. Вы создаете оптимизатор для выбора одного из индексов одного поля, вместо того, чтобы указывать один индекс, который он может использовать для всех трех полей.

Добавьте указатель на таблицу tabjbmaw с тремя полями numeric_line_code, subcode и accountnum.

+0

Я тестирую это сейчас – user1863457

+0

, как быстро это было после добавления нового индекса? –

0

Расширение @Sebas ответ, вы должны выбрать tabjbmaw первое:

SELECT 
    p.sap_article_id, 
    p.numeric_line_code, 
    p.uag_linecode, 
    p.uag_partnum, 
    p.part_description, 
    p.jobber_price, 
    p.jobber_core, 
    p.discount1, 
    p.discount2, 
    p.uom, 
    p.product_category, 
    w.as400_warehouse, 
    w.atp_qty, 
    p.updated, 
    t.regular_discount  
FROM tabjbmaw t 
     LEFT JOIN parts p ON p.numeric_line_code = t.numeric_line_code 
          AND p.sub_code  = t.sub_code  
     JOIN warehouse w ON w.sap_article_id = p.sap_article_id 
WHERE t.accountnum = '73050' 
; 
+0

, если бы это было очень плохой функциональной ошибкой от него: D Но я согласен с тобой, что кажется более логичным – Sebas

+0

Это, конечно же, даст разные результаты, так как это пропустит любые части, которые не соответствуют соединению с tabjbmaw. Кроме того, он включает записи tabjbmaw, которые не совпадают, когда это не было частью результата раньше. Возможно, изменение LEFT JOIN IN INER JOIN приведет к удалению недостающих частей, но не приведет к отсутствию записей tabjbmaw. –

+0

Это не приведет к тем же результатам, что и исходный запрос. Таблица 'LEFT' здесь' tabjbmaw', а не 'parts', как в исходном запросе.Кроме того, я не думаю, что это сильно изменило бы ситуацию; он все равно должен будет выполнить полное сканирование таблицы на 'parts'. –

0

Вы можете попытаться поместить левое соединение в элемент SELECT в качестве подзапроса. Это может «немного ускорить».

Как это:

SELECT 
    p.sap_article_id, 
    p.numeric_line_code, 
    p.uag_linecode, 
    p.uag_partnum, 
    p.part_description, 
    p.jobber_price, 
    p.jobber_core, 
    p.discount1, 
    p.discount2, 
    p.uom, 
    p.product_category, 
    w.as400_warehouse, 
    w.atp_qty, 
    p.updated, 
    (SELECT t.regular_discount FROM tabjbmaw t WHERE t.accountnum = '73050' AND p.numeric_line_code = t.numeric_line_code AND p.sub_code = t.sub_code LIMIT 1)  
FROM 
    part p 
    JOIN warehouse w ON w.sap_article_id = p.sap_article_id; 
+0

Это позволяет получить только один результат из 'tabjbmaw', но исходный запрос позволяет использовать несколько. Кроме того, 'JOIN' почти всегда быстрее, чем подзапросы. –