我有以下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比执行子查询要好得多吗?
以下是两个执行计划 -
答案 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)