mysql NOT IN QUERY优化

时间:2011-05-25 05:54:52

标签: mysql sql query-optimization

我有两个名为:

的表
  1. table_product
  2. table_user_ownned_auction
  3. table_product

    specific_product_id      astatus  ... 
    (primary_key,autoinc)
    --------------------------------------
    1                        APAST    ...
    2                        ALIVE    ...
    3                        ALIVE    ...
    4                        APAST    ... 
    5                        APAST    ...
    

    table_user_ownned_auction

    own_id     specific_product_id   details   
    ----------------------------------------
    1                  1               XXXX
    2                  5               XXXX
    

    我需要选择atatus = APAST,而不是表2中 这意味着,在上面的结构中,table1有3个APAST状态(1,4,5)。但是在表2中,specific_product_id(1,5)只存储了所以我需要选择specific_product_id = 4

    我使用了这个查询

      SELECT * 
        FROM table_product 
       WHERE astatus = 'APAST' 
         AND specific_product_id NOT IN (SELECT specific_product_id 
                                           FROM table_user_ownned_auction )
    

    ......这需要很长时间:

      

    查询耗时115.1039秒

    ......执行。

    EXPLAIN PLAN

    enter image description here

    我如何优化它或以任何其他方式选择我想要的?

2 个答案:

答案 0 :(得分:12)

使用NOT EXISTS

SELECT p.* 
  FROM TABLE_PRODUCT p
 WHERE p.astatus = 'APAST' 
   AND NOT EXISTS (SELECT NULL
                     FROM TABLE_USER_OWNED_AUCTION uoa
                    WHERE uoa.specific_product_id = p.specific_product_id)

使用LEFT JOIN/IS NULL

   SELECT p.* 
     FROM TABLE_PRODUCT p
LEFT JOIN TABLE_USER_OWNED_AUCTION uoa ON uoa.specific_product_id = p.specific_product_id
    WHERE p.astatus = 'APAST' 
      AND uoa.own_id IS NULL

解释

最佳查询可以通过两个表之间比较的列是否为NULL来确定(IE:如果两个表中的specific_product_id的值都可以是NULL)。

附录

确定最佳查询后,至少查看creating indexes (possibly covering indexes)

  • specific_product_id
  • TABLE_PRODUCT.astatus

答案 1 :(得分:7)

尝试在table_user_ownned_auction表上添加索引:

ALTER TABLE table_user_ownned_auction ADD KEY(specific_product_id)

另外,请尝试使用non-exists加入:

SELECT p.*
FROM table_product p
    LEFT JOIN table_user_ownned_auction l
      ON p.specific_product_id = l.specific_product_id
WHERE p.astatus = 'APAST' 
    AND l.specific_product_id IS NULL