mysql - 优化返回大量记录的查询,一种避免数百个连接的方法。这是一个聪明的解决方案吗?

标签 mysql sql database query-optimization rdbms

我对 SQL 不是很了解,我对如何优化查询有以下疑问。我正在使用 MySql

我有这个数据库模式:

enter image description here

这是返回特定商品进入特定市场的最后价格(进入 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/

相关文章:

php - 进行仅显示不包含空值的行的查询

mysql - 是否可以从 MySQL 和 MSSQL 同步两个链接服务器中的两个表?

mysql - 语法错误 MySQL 更新

php - 添加所有行乘以另一个表中的另一行

sql - JOIN或带有exists子句的Correlated子查询,哪个更好

sql - 错误 : ALTER DATABASE statement not allowed within multi-statement transaction

mysql - 连接到外部 mysql 数据库时出现问题

sql - 使用 Entity Framework == EntityException 并发访问数据库

mysql - 如何优化此 IP 到位置查找查询?

c# - 数据库返回在启动时有效,但在更新时无效