要弄清楚如何优化您的查询,我们首先必须准确地总结出它正在选择的内容,以便我们可以在更改内容时保留该信息。
您的查询是做什么的
所以,看起来我们需要以下内容
- GROUP BY 子句将结果限制为每行最多一行
catalog_id
smallerTable1.cont = 'Y'
, insanelyBigTable.type IN ('111','222','33')
, 和buyer_id = 'xxx'
似乎是查询的过滤器。
- 我们想要来自
insanlyBigTable
and ...的数据catalogpartner
?我猜这是catalogpartner
smallTable1,因为它被链接到其他表。id
smallerTable
catalog_id
我不确定在子句中包含buyer_id
过滤器的目的是什么ON
,但除非您以不同的方式告诉我,否则我会假设它在ON
子句中的事实并不重要。
查询的重点
基于该 GROUP BY 语句,我不确定查询的意图。您将只获得 中的每行catalog_id
,insanelyBigTable
但您似乎并不关心它是哪一行。事实上,您完全可以运行此查询的事实是由于MySQL 中的一个特殊的非标准功能,它允许您选择未出现在 GROUP BY 语句中的列......但是,您无法选择 WHICH列。这意味着您可以从 4 个不同的行中获取每个所选项目的信息。
根据列名,我最好的猜测是,您正在尝试带回与给定买家购买的商品在同一目录中的商品列表,但每个目录不超过一个商品。此外,您希望通过catalogpartner
表格的id
.
因此,可能类似于亚马逊的“您可能喜欢这些商品,因为您购买了这些其他商品”功能。
新的查询
我们希望每个 insanlyBigTable.catalog_id 有 1 行,根据过滤后在 smallTable1 中存在的 catalog_id。
SELECT
ibt.description_short,
ibt.id AS insanlyBigTable,
ibt.type AS insanlyBigTableLol,
(
SELECT smallerTable1.id FROM smallerTable1 st
WHERE st.buyer_id = 'xxx'
AND st.cont = 'Y'
AND st.catalog_id = ibt.catalog_id
LIMIT 1
) AS catalogpartner_id
FROM insanlyBigTable ibt
WHERE ibt.id IN (
SELECT (
SELECT ibt.id AS ibt_id
FROM insanlyBigTable ibt
WHERE ibt.catalog_id = sti.catalog_id
LIMIT 1
) AS ibt_id
FROM (
SELECT DISTINCT(catalog_id) FROM smallerTable1 st
WHERE st.buyer_id = 'xxx'
AND st.cont = 'Y'
AND EXISTS (
SELECT * FROM insanlyBigTable ibt
WHERE ibt.type IN ('111','222','33')
AND ibt.catalog_id = st.catalog_id
)
) AS sti
)
此查询应生成与原始查询相同的结果,但它将事物分解为更小的查询,以避免在insanlyBigTable
.
试一试,如果您遇到问题,请告诉我。