2013-03-19 71 views
1

你好,我试图运行这个选择语句使用这个查询,它需要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

什么样的JOIN你要对仓库表?您是否尝试将'73050'= tabjbmaw.accountnum移至WHERE子句? – Melanie 2013-03-19 19:24:24

+2

不,如果从LEFT JOIN部分删除该语句将是一个可怕的错误。首先,优化器在JOIN和WHERE子句中工作相同,其次插入到WHERE子句中的筛选器使关联的表INNER加入,在这种情况下这是不正确的,因为他希望进行OUTER连接。 – Sebas 2013-03-19 19:28:50

+0

我们需要空值返回折扣不存在,所以移动到最后并没有帮助我们。它需要留在那里 – user1863457 2013-03-19 19:29:38

回答

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,但只有每个字段的一个三项指标,并具有所有的字段没有索引。您正在使优化器选择一个字段索引中的一个,而不是提供可用于所有三个字段的索引。

使用三个字段numeric_line_code,subcode和accountnum在表tabjbmaw上添加索引。

+0

我现在正在测试这个 – user1863457 2013-03-19 19:41:29

+0

添加新索引后速度有多快? – 2013-03-19 19:50:27

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 2013-03-19 19:42:44

+0

这当然会给出不同的结果,因为它会错过任何与tabjbmaw不匹配的部分。此外,它还包含不匹配的tabjbmaw记录,当它不是之前结果的一部分时。也许将LEFT JOIN改为INNER JOIN会删除缺少的部分,但不会引入缺少的tabjbmaw记录。 – 2013-03-19 19:45:18

+0

这不会产生与原始查询相同的结果。这里的'LEFT'表是'tabjbmaw',而不是原始查询中的'parts'。另外,我不认为这会有很大的区别。它仍然需要对'parts'进行全表扫描。 – 2013-03-19 19:46:03

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'几乎总是比子查询更快。 – 2013-03-19 19:57:12