简体   繁体   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

Result(= 150 products): products are validated in ebay_shop && amazon_shop in year 2007 结果(= 150个产品):产品于2007年在ebay_shop && amazon_shop中进行了验证

SELECT ebay_shop.product_id
FROM ebay_shop
WHERE ebay_shop.validated = 2010

Result(= 4000 products): products are validated in ebay_shop in year 2010 结果(= 4000个产品):产品于2010年在ebay_shop中进行了验证

Question: i want to find products which aren't validated to 2010 of 2007 list, products have in 2007 but not in 2010. 问题:我想查找未经过2010年清单验证的产品,产品已进入2007年清单,但没有经过2010年验证。

My 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
AND NOT IN (SELECT ebay_shop.product_id
            FROM ebay_shop
            WHERE ebay_shop.validated = 2010)

My query is very slow(~60s) 150 find in 4000 records. 我的查询非常慢(〜60s)在4000条记录中找到150个。 I need help to improve this query. 我需要帮助来改善此查询。

NOT IN is terrible on performance. NOT IN在性能上很糟糕。 Probably the best way is to do a LEFT JOIN for your 2010 and then qualify it is NULL... Any record that IS found, throw it out, just keep the ones that return NULL via the join qualifier. 最好的方法可能是为您的2010年做一个LEFT JOIN,然后将其限定为NULL ...找到的任何记录,将其丢弃,只保留那些通过连接限定符返回NULL的记录。

In addition, ensure you have an index on your ebay shop and amazon shops based on YEAR AND PRODUCT via index ( validated, product_id ). 另外,请确保您在eBay商店和亚马逊商店中都有基于YEAR和PRODUCT的索引(通过索引(已验证,product_id))。 Reason to have the year first, to keep all the common year as small set, then cycle all products within that. 首先要有年份,将所有普通年份保持在较小的年份,然后在其中循环所有产品。 Then, the index would also be optimized for the respective join too. 然后,索引也将针对相应的连接进行优化。

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

I realize this isn't really an answer but more of a different study case! 我意识到这并不是一个真正的答案,而是更多的不同的学习案例!

I also use "NOT IN" but in a different context. 我也使用“ NOT IN”,但使用的是其他上下文。 I get the result I what but the query takes more than 10 seconds for a table with about 300 records. 我得到的结果是什么,但是对于大约300条记录的表,查询要花费10秒钟以上的时间

Here is the query: 这是查询:

(
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

The field "numero_mandataire" is the constant in both tables. 两个表中的字段“ numero_mandataire”是常数。 In the result, i Want all records from the table membre_mandataire and UNION or JOIN all records where "numero_mandataire" cannot be found in the table mandataires_actifs . 结果,我希望从表membre_mandataire中获取所有记录,并希望UNION或JOIN在表mandataires_actifs中找不到“ numero_mandataire”的所有记录。

I guess the solution for me would be to go with "LEFT JOIN" instead of "UNION" but I am still stuck with "NOT IN". 我想对我来说解决方案是使用“ LEFT JOIN”而不是“ UNION”,但我仍然坚持使用“ NOT IN”。 I've been trying for a while and I can't make it work. 我已经尝试了一段时间,但无法正常工作。

I am learning MySQL but looks like i'm not quite there yet! 我正在学习MySQL,但看起来我还没到那里!

Thanks for any help! 谢谢你的帮助!

  • Blaise 布莱斯

@DRapp wrote a fine workaround and I want to add an other idea... @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 

and then: 接着:

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