0

私は PDO Mysql を使用しており、データベース内の製品の最も安いオファーを選択するように要求しました。それは問題なく動作しますが、唯一の問題は遅いことです (200 のオファーの場合 (それでも返されるのに 25 しかありません))、ほぼ 1 秒かかります。

私は SQL の専門家ではないので、この問題についてあなたの助けを求めています。リクエストは次のとおりです。必要に応じて、より多くの情報を提供させていただきます。

SELECT
            mo.id AS id, 
            mo.stock AS stock, 
            mo.price AS price,
            mo.promotional_price AS promotional_price, 
            mo.picture_1 AS picture_1, 
            mo.picture_2 AS picture_2, 
            mo.picture_3 AS picture_3, 
            mo.picture_4 AS picture_4, 
            mo.picture_5 AS picture_5, 
            mo.title AS title, 
            mo.description AS description, 
            mo.state AS state, 
            mo.is_new AS is_new, 
            mo.is_original AS is_original, 
            c.name AS name, 
            u.id AS user_id, 
            u.username AS username, 
            u.postal_code AS postal_code,
            p.name AS country_name, 
            ra.cache_rating_avg AS cache_rating_avg, 
            ra.cache_rating_nb AS cache_rating_nb, 
            GROUP_CONCAT(md.delivery_mode_id SEPARATOR ', ') AS delivery_mode_ids, 
            GROUP_CONCAT(ri.title SEPARATOR ', ') AS delivery_mode_titles

        FROM 
            mp_offer mo, catalog_product_i18n c,
            ref_country_i18n p, mp_offer_delivery_mode md,
            ref_delivery_mode r, 
            ref_delivery_mode_i18n ri, user u 

        LEFT JOIN mp_user_review_rating_i18n ra 
            ON u.id = ra.user_id 

        WHERE (mo.product_id = c.id 
                AND mo.culture = c.culture 
                AND mo.user_id = u.id 
                AND u.country_id = p.id 
                AND mo.id = md.offer_id
                AND md.delivery_mode_id = ri.id 
                AND mo.culture = ri.culture) 
            AND (mo.culture = 1
                AND p.culture = 1) 
            AND mo.is_deleted = 0
            AND mo.product_id = 60 
            AND ((u.holiday_start IS NULL)
                OR (u.holiday_start = '0000-00-00') 
                OR (u.holiday_end IS NULL)
                OR (u.holiday_end = '0000-00-00') 
                OR (u.holiday_start > '2012-05-03')
                OR (u.holiday_end < '2012-05-03')) 
            AND mo.stock > 0
        GROUP BY mo.id 
        ORDER BY IF (mo.promotional_price IS NULL,
                    mo.price,
                    LEAST(mo.price, mo.promotional_price)) ASC 

        LIMIT 25 OFFSET 0;

「文化」が 1 に設定されていて、削除されておらず、在庫があり、販売者が休日ではない特定の商品のオファーを受け取ります。価格(ある場合はpromotional_price)で注文します。

LEAST は遅い関数ですか?

EXPLAIN の出力は次のとおりです。

id  select_type table   type    possible_keys                                                                       key     key_len ref                                 rows    Extra
1   SIMPLE      c       const   PRIMARY,catalog_product_i18n_product,catalog_product_i18n_culture                   PRIMARY 8       const,const                         1       "Using temporary; Using filesort"
1   SIMPLE      mo      ref     PRIMARY,culture,is_deleted,product_id,user_id                                       culture 4       const                               3       "Using where with pushed condition"
1   SIMPLE      u       eq_ref  PRIMARY,user_country                                                                PRIMARY 4       database.mo.user_id                 1       "Using where with pushed condition"
1   SIMPLE      p       eq_ref  PRIMARY,ref_country_i18n_culture                                                    PRIMARY 8       database.u.country_id,const         1   
1   SIMPLE      r       ALL     NULL                                                                                NULL    NULL    NULL                                3       "Using join buffer"
1   SIMPLE      ra      ALL     NULL                                                                                NULL    NULL    NULL                                4   
1   SIMPLE      md      ref     PRIMARY,fk_offer_has_delivery_mode_delivery_mode1,fk_offer_has_delivery_mode_offer1 PRIMARY 4       database.mo.id                      2   
1   SIMPLE      ri      eq_ref  PRIMARY                                                                             PRIMARY 2       database.md.delivery_mode_id,const  1

このリクエストの最適化にご協力いただき、ありがとうございます。

J

4

1 に答える 1

0

from句に含めたref_delivery_modeテーブルを使用していません。テーブル結果のデカルト積の原因になっています。

于 2012-05-03T09:44:15.510 に答える