[英]MySQL, WHERE NOT IN very slow query?
SELECT product_id
FROM ebay_shop
LEFT JOIN amazon_shop ON ebay_shop.product_id = amazon_shop.product_id
WHERE ebay_shop.validated = 2007
AND amazon_shop.validated = 2007
结果(= 150个产品):产品于2007年在ebay_shop && amazon_shop中进行了验证
SELECT ebay_shop.product_id
FROM ebay_shop
WHERE ebay_shop.validated = 2010
结果(= 4000个产品):产品于2010年在ebay_shop中进行了验证
问题:我想查找未经过2010年清单验证的产品,产品已进入2007年清单,但没有经过2010年验证。
我的查询:
SELECT product_id
FROM ebay_shop
LEFT JOIN amazon_shop ON ebay_shop.product_id = amazon_shop.product_id
WHERE ebay_shop.validated = 2007
AND amazon_shop.validated = 2007
AND NOT IN (SELECT ebay_shop.product_id
FROM ebay_shop
WHERE ebay_shop.validated = 2010)
我的查询非常慢(〜60s)在4000条记录中找到150个。 我需要帮助来改善此查询。
NOT IN在性能上很糟糕。 最好的方法可能是为您的2010年做一个LEFT JOIN,然后将其限定为NULL ...找到的任何记录,将其丢弃,只保留那些通过连接限定符返回NULL的记录。
另外,请确保您在eBay商店和亚马逊商店中都有基于YEAR和PRODUCT的索引(通过索引(已验证,product_id))。 首先要有年份,将所有普通年份保持在较小的年份,然后在其中循环所有产品。 然后,索引也将针对相应的连接进行优化。
SELECT STRAIGHT_JOIN
es.product_id
FROM
ebay_shop eshop
LEFT JOIN amazon_shop ashop
ON eshop.validated = ashop.validated
AND eshop.product_id = ashop.product_id
LEFT JOIN ebay_shop ebay2
on ebay2.validated = 2010
and ebay2.product_id = eshop.product_id
WHERE
eshop.validated = 2007
and ebay2.validated is null
我意识到这并不是一个真正的答案,而是更多的不同的学习案例!
我也使用“ NOT IN”,但使用的是其他上下文。 我得到的结果是什么,但是对于大约300条记录的表,查询要花费10秒钟以上的时间 。
这是查询:
(
SELECT (
'inscrit'
) AS
TYPE , membre_mandataire.id AS id, membres.prenom AS prenom, membres.nom_de_famille AS nom_de_famille, membre_mandataire.photo AS photo, membre_mandataire.niveau_qualification AS niveau_qualification, membre_mandataire.numero_mandataire AS numero_mandataire
FROM membres, membre_mandataire
WHERE membre_mandataire.id_membre = membres.id
AND membre_mandataire.confirme = 'Y'
AND membre_mandataire.visible_dans_liste = 'Y'
)
UNION (
SELECT (
'actif'
) AS
TYPE , mandataires_actifs.id AS id, mandataires_actifs.prenom AS prenom, mandataires_actifs.nom_de_famille AS nom_de_famille, mandataires_actifs.photo AS photo, mandataires_actifs.niveau_qualification AS niveau_qualification, mandataires_actifs.numero_mandataire AS numero_mandataire
FROM mandataires_actifs, membre_mandataire
WHERE (
mandataires_actifs.numero_mandataire
) NOT
IN (
SELECT membre_mandataire.numero_mandataire
FROM membre_mandataire
WHERE membre_mandataire.confirme = 'Y'
AND membre_mandataire.visible_dans_liste = 'Y'
)
)
ORDER BY nom_de_famille ASC
两个表中的字段“ numero_mandataire”是常数。 结果,我希望从表membre_mandataire中获取所有记录,并希望UNION或JOIN在表mandataires_actifs中找不到“ numero_mandataire”的所有记录。
我想对我来说解决方案是使用“ LEFT JOIN”而不是“ UNION”,但我仍然坚持使用“ NOT IN”。 我已经尝试了一段时间,但无法正常工作。
我正在学习MySQL,但看起来我还没到那里!
谢谢你的帮助!
@DRapp写了一个很好的解决方法,我想添加另一个想法...
SELECT group_concat(product_id)
FROM ebay_shop
LEFT JOIN amazon_shop ON ebay_shop.product_id = amazon_shop.product_id
WHERE ebay_shop.validated = 2007
AND amazon_shop.validated = 2007
接着:
SELECT product_id
FROM ebay_shop
LEFT JOIN amazon_shop ON ebay_shop.product_id = amazon_shop.product_id
WHERE ebay_shop.validated = 2007
AND amazon_shop.validated = 2007
AND NOT IN (1,2,3,4) /* results from first query */
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.