MySQL,在哪里不是很慢的查询?

时间:2011-11-25 03:05:34

标签: mysql

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条记录。我需要帮助才能改进此查询。

3 个答案:

答案 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 */