我对 SQL 不是很了解,我对如何优化查询有以下疑问。我正在使用 MySql
我有这个数据库模式:
这是返回特定商品进入特定市场的最后价格(进入 Market_Commodity_Price_Series 表的最后日期)的查询。
它包含很多连接来检索所有相关信息:
SELECT MCPS.id AS series_id,
MD_CD.market_details_id AS market_id,
MD_CD.commodity_details_id AS commodity_id,
MD.market_name AS market_name,
MCPS.price_date AS price_date,
MCPS.avg_price AS avg_price,
CU.ISO_4217_cod AS currency,
MU.unit_name AS measure_unit,
CD.commodity_name_en,
CN.commodity_name
FROM Market_Commodity_Price_Series AS MCPS
INNER JOIN MeasureUnit AS MU ON MCPS.measure_unit_id = MU.id
INNER JOIN Currency AS CU ON MCPS.currency_id = CU.id
INNER JOIN MarketDetails_CommodityDetails AS MD_CD ON MCPS.market_commodity_details_id = MD_CD.id
INNER JOIN MarketDetails AS MD ON MD_CD.market_details_id = MD.id
INNER JOIN CommodityDetails AS CD ON MD_CD.commodity_details_id = CD.id
INNER JOIN CommodityName AS CN ON CD.id = CN.commodity_details_id
INNER JOIN Languages AS LN ON CN.language_id = LN.id
WHERE MD.id = 4
AND CD.id = 4
AND LN.id=1
ORDER BY price_date DESC LIMIT 1
我的疑问是:使用前面的查询,我从 Market_Commodity_Price_Series 表中提取与特定商品相关的所有记录到特定市场,进行大量连接,根据price_date 字段并限制为最后一个。
我认为它可以扩展,因为我可以有很多记录(因为 Market_Commodity_Price_Series 表包含每日信息)。
这个查询有效,但我认为可以用更聪明的方式完成。
所以我想我可以做这样的事情:
1) 使用如下查询选择与特定商品进入特定市场的最后价格相关的记录:
SELECT measure_unit_id,
currency_id,
market_commodity_details_id,
MAX(price_date) price_date
FROM Market_Commodity_Price_Series AS MCPS
INNER JOIN MarketDetails_CommodityDetails AS MD_CD ON MCPS.market_commodity_details_id = MD_CD.id
WHERE MD_CD.market_details_id = 4
AND MD_CD.commodity_details_id = 4
GROUP BY measure_unit_id, currency_id, market_commodity_details_id
返回与此信息相关的单个记录:
measure_unit_id currency_id market_commodity_details_id price_date
--------------------------------------------------------------------------------
1 2 24 05/10/2017
像使用表格一样使用此输出(我不知道确切的名称,也许是 View ,是吗?)并将此“表格”连接到 MeasureUnit、Currency、MarketDetails 中的其他必需信息, CommodityDetails、CommodityName 和 Languages 表。
我认为它可能会更好,因为通过这种方式我使用 MAX(price_date) price_date 仅将与最新价格相关的记录提取到 Market_Commodity_Price_Series而是获取所有记录,排序并限制为最新记录。
此外,大多数 JOIN 操作都是针对前一个查询返回的单个记录执行的,而不是针对我的第一个查询版本返回的所有记录执行的(可能有数百或数千条) .
这可能是一个明智的解决方案吗?
如果是...将此查询的输出(将其视为一个表)与其他表连接起来的正确语法是什么?
最佳答案
JOIN
——尤其是在主键上——不一定很昂贵。看起来您的联接遵循数据模型。
在不了解其性能特征的情况下,我不会开始优化查询。运行需要多长时间?正在对多少条记录进行排序以获取最新记录?
您的 WHERE
子句似乎在很大程度上限制了数据。您还可以设置一个索引来帮助处理 WHERE
子句——但是,由于字段来自不同的表,因此使用索引或全部使用索引可能会很棘手。
您有一个有点难以遵循的复杂数据模型。由于多个 n-m 关系,您似乎可能得到笛卡尔积。如果是这样,这会对性能产生重大影响,并且沿着每个维度预先聚合数据是可行的方法。
但是,如果不了解当前查询的行为方式,我不会开始优化查询。
关于mysql - 优化返回大量记录的查询,一种避免数百个连接的方法。这是一个聪明的解决方案吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46621414/