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个产品):产品在ebay_shop&&amp ;; amazon_shop在2007年
SELECT ebay_shop.product_id
FROM ebay_shop
WHERE ebay_shop.validated = 2010
结果(= 4000种产品):产品在2010年的ebay_shop中得到验证
问题:我想找到未经过2007年度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)
我的查询非常慢(约60秒)150找到4000条记录。我需要帮助才能改进此查询。
答案 0 :(得分:4)
NOT IN在表现上很糟糕。可能最好的方法是为你的2010做一个LEFT JOIN然后限定它是NULL ...任何找到的记录,抛出它,只保留通过连接限定符返回NULL的记录。
此外,请确保您的ebay商店和亚马逊商店的索引基于年份和产品的索引(validated,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
答案 1 :(得分:1)
我意识到这不是一个真正的答案,而是更多不同的研究案例!
我也使用“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但看起来我还没到那里!
感谢您的帮助!
答案 2 :(得分:0)
@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 */