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