mysql NOT IN QUERY 优化
Posted
技术标签:
【中文标题】mysql NOT IN QUERY 优化【英文标题】:mysql NOT IN QUERY optimize 【发布时间】:2011-05-25 05:54:52 【问题描述】:我有两个表命名为:
-
table_product
table_user_ownned_auction
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 中。
这意味着,在上述结构表 1 中有 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 秒
...执行。
解释计划
我怎样才能优化它或任何其他方式来选择我想要的?
【问题讨论】:
【参考方案1】:使用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
说明
最佳查询可以通过两个表之间比较的列是否可为空来确定(即:如果任一表中的specific_product_id
的值可以是NULL
)。
NOT IN
or NOT EXISTS
is the best choice in mysql
如果NOT nullable, `LEFT JOIN/IS NULL is the best choice in MySQL
附录
确定最佳查询后,请至少查看creating indexes (possibly covering indexes):
specific_product_id
TABLE_PRODUCT.astatus
【讨论】:
我喜欢你的解决方案。我正在学习mysql。您能否解释一下当 uoa.specific_product_id != p.specific_product_id 时在 NOT EXISTS(..) 的子查询中将选择什么 @Sandeep:NOT
执行反转,将uoa.specific_product_id = p.specific_product_id
更改为uoa.specific_product_id != p.specific_product_id
。
附录一有错别字 -> 一次。
我阅读了您引用的article,似乎LEFT JOIN/IS NULL
和NOT IN
之间没有性能差异。因此,您可以得出结论,您可以始终使用 NOT IN
并且您始终被覆盖。引用文章中比较两者的引述:“算法实际上是相同的,并且查询在同一时间完成。”【参考方案2】:
尝试在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
【讨论】:
@gowri: 那也可能是因为查询计划被缓存了 使用准确的字段名而不是SELECT *
以上是关于mysql NOT IN QUERY 优化的主要内容,如果未能解决你的问题,请参考以下文章