2016-08-15 3 views
0

So meine MySQL-Abfrage wurde für 25 Sekunden jedes Mal geladen. Ich habe die Abfrage geteilt und herausgefunden, dass sie ohne eine der WHERE-Bedingungen perfekt funktioniert. Bedingung verursachendes Problem ist:MySQL exec Zeit schwarze Magie

eshop_products.id IN 
(SELECT product-id 
    FROM eshop_productCombinations 
    WHERE eshop_productCombinations.recomended = 1 
    GROUP BY product-id) 

Ohne diese Bedingung dauerte Abfrage 0,019 Sekunden zu laden. ABER, wenn ich diese wählt separat ausführen, dauert es nur 0,026 Sekunden laden:

SELECT product-id 
FROM eshop_productCombinations 
WHERE eshop_productCombinations.recomended = 1 
GROUP BY product-id 

Hat jemand eine Ahnung, was mit meiner Haupt-Abfrage falsch ist? Vielen Dank.

Hier vollständige Abfrage (obwohl ich es für jeden nützlich sein würde nicht denken):

SELECT 
CAST(
    SUBSTRING_INDEX(
    GROUP_CONCAT(
     price_with_vat ORDER BY IF(eshop_products_cache.`stock` > 0, 1, 0) DESC, 
     IF(
     eshop_products.`type_default_price`=2,eshop_products_cache.`price_with_vat`, 
     if(
      eshop_products.`type_default_price`=0,eshop_products_cache.`default`,null 
     ) 
    ) DESC, 
     IF(eshop_products.`type_default_price`=1,eshop_products_cache.`price`, null) ASC 
    ), 
    ", 
    ", 
    1 
) AS DECIMAL(10,2) 
) AS `price_with_vat`, 
SUBSTRING_INDEX(
    GROUP_CONCAT(
    eshop_products_cache.combination_id ORDER BY IF(eshop_products_cache.`stock` > 0, 1, 0) DESC, 
    IF(
     eshop_products.`type_default_price`=2, 
     eshop_products_cache.`price_with_vat`, 
     if(
     eshop_products.`type_default_price`=0, 
     eshop_products_cache.`default`, 
     null 
    ) 
    ) DESC, 
    IF(eshop_products.`type_default_price`=1,eshop_products_cache.`price`, null) 
    ASC 
), 
    ", 
    ", 
    1 
) AS `combination_id`, 
if(eshop_products.id in ('5993', '6144', '6663', '5120', '5376', '5632', '5888', '6400', '6656', '5121', '5377', '5633'), 1, 0) AS new 
FROM `eshop_products` LEFT JOIN `eshop_products_cache` ON eshop_products_cache.product_id=eshop_products.`id` WHERE 
(
    (
    (
     eshop_products.stockType = 2 AND eshop_products_cache.stock > 0 
    ) 
    OR eshop_products.stockType <> 2 
) 
) 
AND 
(
    price_with_vat > 0 
) 
AND 
(
    eshop_products.recomended = 1 
    OR 
    eshop_products.id IN (
    SELECT `product-id` FROM eshop_productCombinations WHERE eshop_productCombinations.recomended = 1 GROUP BY `product-id` 
) 
) 
AND 
(
    eshop_products.active = '1' 
) 
AND (dateStartPublish <= NOW() OR dateStartPublish IS NULL) 
AND (dateStopPublish >= NOW() OR dateStopPublish IS NULL) 
GROUP BY `eshop_products`.`id`, `eshop_products_cache`.`product_id` ORDER BY RAND() ASC LIMIT 5 
+0

nicht versuchen, sarkastisch klingen, aber es ist dieser Teil 'eshop_products.id IN (SELECT Produkt-ID VON eshop_productCombinations WHERE eshop_productCombinations.recomended = 1 GROUP BY Produkt-ID)' – e4c5

+1

Haben Sie vielleicht vor zu fragen, wie dies c ein beschleunigt werden? Dann poste deine EXPLAIN-Ausgabe und gebe einige Informationen über deine Tabellen, vorzugsweise die Show-Create-Tabelle. – e4c5

+0

Ich denke, ich bin wirklich dumm, ich sehe nicht, wo das Problem ist –

Antwort

2

von Anthony Vorgeschlagen hat Unterabfrage unten mit Code ersetzt werden:

EXISTS (
    SELECT 1 FROM eshop_productCombinations 
    WHERE eshop_productCombinations.recomended = 1 
    AND product-id = eshop_products.id) 
+0

Fyi, neuere Versionen von MySQL werden versuchen, IN-Klauseln automatisch in EXISTS-Klauseln umzuwandeln, aber es ist nicht immer eine einfache Transformation, die der Server einfach und sicher anwenden kann. Deshalb ist es gut zu verstehen, Warum * bestimmte SQL-Abfrageentwürfe sind mehr Steuer-und Design-Abfragen mit diesem Verständnis im Hinterkopf. – Anthony

+0

Und ich bin mir auch nicht sicher, ob eine Gruppe in dieser Unterabfrage ist. Sie haben keine Aggregatfunktionen, die sie benötigen, und die EXISTS-Funktion profitiert wahrscheinlich nicht so sehr, wie Sie denken, dass die Ergebnisse der Unterabfrage eindeutig sein müssen. – Anthony

+0

Es ist auch nur ein Teil der alten CMS (die auf älteren Technologien basiert und dringend in naher Zukunft neu aufgebaut werden muss), so wird dies in naher Zukunft definitiv nützlich sein. Vielen Dank. –