0

我有一个这样的查询:

SELECT    insanlyBigTable.description_short, 
          insanlyBigTable.id AS insanlyBigTable, 
          insanlyBigTable.type AS insanlyBigTableLol, 
          catalogpartner.id AS catalogpartner_id
FROM insanlyBigTable
INNER JOIN smallerTable ON smallerTable.id = insanlyBigTable.catalog_id
INNER JOIN smallerTable1 ON smallerTable1.catalog_id = smallerTable.id 
  AND smallerTable1.buyer_id = 'xxx'
WHERE smallerTable1.cont = 'Y' AND insanlyBigTable.type IN ('111','222','33') 
GROUP BY smallerTable.id;

现在,当我第一次运行查询时,它会将巨型表复制到临时表中......我想知道如何防止这种情况发生?我正在考虑嵌套查询,甚至是反向连接(不确定效果是否会运行得更快),但这很好,不是很好。还有其他建议吗?

4

1 回答 1

1

要弄清楚如何优化您的查询,我们首先必须准确地总结出它正在选择的内容,以便我们可以在更改内容时保留该信息。

您的查询是做什么的

所以,看起来我们需要以下内容

  • GROUP BY 子句将结果限制为每行最多一行catalog_id
  • smallerTable1.cont = 'Y', insanelyBigTable.type IN ('111','222','33'), 和buyer_id = 'xxx'似乎是查询的过滤器。
  • 我们想要来自insanlyBigTableand ...的数据catalogpartner?我猜这是catalogpartnersmallTable1,因为它被链接到其他表。idsmallerTablecatalog_id

我不确定在子句中包含buyer_id过滤器的目的是什么ON,但除非您以不同的方式告诉我,否则我会假设它在ON子句中的事实并不重要。

查询的重点

基于该 GROUP BY 语句,我不确定查询的意图。您将只获得 中的每行catalog_idinsanelyBigTable但您似乎并不关心它是哪一行。事实上,您完全可以运行此查询的事实是由于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.

试一试,如果您遇到问题,请告诉我。

于 2013-10-24T14:17:19.480 回答