使用子查询和连接改进大型查询

时间:2015-12-01 04:24:50

标签: mysql sql

我有以下SQL查询,需要8秒才能运行。我如何优化以下声明?

SELECT
       p.id, territory_id, p.platform_id,
       GROUP_CONCAT(DISTINCT COALESCE(language_of_content_primary_id, base_language_id), ',', IFNULL(languages_of_content_additional, '')) languages,
       p.store_url, allows_free_streaming, requires_paid_subscription, group_concat(sd_retail_price) purchase
FROM
    main_iteminstance i INNER JOIN main_territorypricing p ON p.item_id=i.id
WHERE
    (doesnt_exist_on_store_anymore=0 AND p.store_url IS NOT NULL)
    AND
    (master_id=%s OR tv_series_id IN (SELECT id FROM main_iteminstance WHERE master_id=%s))
GROUP BY
    territory_id, platform_id''', (self.pk, self.pk))

请注意,以下内容在0.03s中运行 -

               WHERE
               (doesnt_exist_on_store_anymore=0 AND p.store_url IS NOT NULL)
               AND
               (master_id=33568)

但是使用子查询会添加额外的8s -

               WHERE
               (doesnt_exist_on_store_anymore=0 AND p.store_url IS NOT NULL)
               AND
               (master_id=%s OR tv_series_id IN (SELECT id FROM main_iteminstance WHERE master_id=%s))

无论出于何种原因,似乎当我把它分成两个查询时它表现得比一个好得多,这就是我现在所拥有的 -

tv_series_ids = cursor.execute('SELECT id FROM table WHERE master_id=%s)

新的WHERE子句 -

WHERE
(doesnt_exist_on_store_anymore=0 AND p.store_url IS NOT NULL)
AND
(master_id=%s OR tv_series_id IN %s)

有人可以向我解释为什么预先获取ID比执行子查询要好得多吗?

以下是两个执行计划 -

enter image description here

1 个答案:

答案 0 :(得分:1)

你可以移动第二个

AND
(master_id=%s OR tv_series_id IN (SELECT id FROM main_iteminstance WHERE master_id=%s))

使用JOIN这样的FROM部分

FROM
    main_iteminstance i INNER JOIN main_territorypricing p ON p.item_id=i.id
    INNER JOIN main_iteminstance i2 ON (i.tv_series_id = i2.id OR i.master_id=%s)
WHERE
    (doesnt_exist_on_store_anymore=0 AND p.store_url IS NOT NULL)