优化SQL请求

时间:2012-05-03 09:21:51

标签: mysql sql optimization request

我正在使用PDO Mysql,并请求为我的数据库中的产品选择最便宜的优惠。它工作正常,唯一的问题是它很慢(200个报价(仍然只有25个报价))它需要几乎一秒钟,这比我的目标要高很多。

我不是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,未删除,有一些库存且卖家不在假期。我按价格订购(promotion_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

提前感谢您对优化此请求的帮助。

Ĵ

1 个答案:

答案 0 :(得分:0)

您没有使用from子句中包含的ref_delivery_mode表。它导致了笛卡尔乘积表的结果。