繁体   English   中英

MySQL,哪里查询不是很慢?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM