繁体   English   中英

如何优化我的mysql查询以更快地检索数据

[英]How to optimize my mysql query to retrieve data faster

我有一个独立的表,我们通过每周工作插入它的数据,并在我们的搜索模块中检索数据。

当我执行以下选择查询需要很长时间(大约15秒)时,该表有大约4百万条记录(并且会变大)。 我正在使用MySql DB。

SELECT 
    v.venueId,
    (SELECT 
            MIN(totalPerPerson)
        FROM
            PricingArtifact pa
        WHERE
            pa.venueId = v.venueId
                AND pa.mealId IN (SELECT
                    m.mealId
                FROM
                    Meal m,
                    MealDay md
                WHERE
                    m.mealId = md.mealId
                        AND m.mealDeletedAt IS NULL
                        AND md.mealDayDeletedAt IS NULL
                        AND m.venueId = v.venueId)) AS minPrice
FROM
    Venue v

请注意

  • 场地表只有12条记录。
  • 我在pricingArtifact表中有venueId,totalPerPerson的索引。
  • 我尝试加入而不是子查询,它给出了相同的结果。
  • 用餐和用餐日表每个不到100个记录。

如果你只是寻找场地和每人的最低总数,你可以直接从pricingArtifact下来,而没有实际的Venue作为pricingArtifacts具有场地ID ...除非你也想要场地描述数据。

通过传递属性,如果V.VenueID = PA.VenueID,则可以在不使用场地表的情况下将PA.VenueID连接到M.VenueID。 同样,PA.MealID可以直接连接到膳食和MealDay表。

现在,您还提到了400万条记录表。 您的相关查询(查询min()值perPerson / perVenue是非常昂贵的,因为您已经遇到过,因为它对第一个表中的每个记录执行子查询。您是否真的需要返回所有历史记录,或者是否有一些DATE字段,例如你只关心最后的活动...说30天?一旦数据完成,它是否真的改变了?可能保留一个汇总表作为分析定价率的基础。

现在,索引。 我建议如下。

table            index
PricingArtifact  (venueID, mealID, totalPerPerson )
Meal             (mealID, MealDeletedAt )
MealDay          (mealID, MealDayDeletedAt )


SELECT
      PA.venueID
      MIN( PA.TotalPerPerson ) as VenueMinPerPerson
   from
      PricingArtifact PA
         JOIN meal M
             ON PA.MealID = M.MealID
            AND M.MealDeletedAt IS NULL
         JOIN MealDay MD
             ON PA.MealID = MD.MealID
            AND MD.MealDayDeletedAt Is NULL

我想你根本不需要加入venue ,如果真的只有12个。

SELECT pa.venueID, MIN(PA.TotalPerPerson) as minPrice
FROM PricingArtifact pa
WHERE EXISTS (SELECT 1
              FROM Meal m JOIN
                   MealDay md
                   ON m.mealId = md.mealId
              WHERE m.mealDeletedAt IS NULL AND
                    md.mealDayDeletedAt IS NULL AND
                    pa.mealId = m.mealId
             )
GROUP BY pa.venueId;

对于此查询,您需要Meal(mealId, mealDeletedAt)MealDay(mealId, mealDayDeletedAt)

您的查询有一些好奇心:

  • 我通常不会将表达式MIN(totalPerPerson)描述为“MinTotalPrice”。
  • MealMailDayPriceArtifact上的PriceArtifact都在同一列上。 这看起来很奇怪。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM