【发布时间】:2021-12-30 07:13:10
【问题描述】:
我目前正在优化具有许多连接表的系统。
我现在正在处理的部分是显示表格orders。问题是在这个表中还有很多我正在查询的关系(大约 10 个)。问题本身在于查询那么多关系。我一直在使用 Eloquent + with() 方法进行预加载,但页面已经变慢了,尽管它的订单不到 3 000 个。问题是在表格中我还打印了 1:N 关系中的数据(例如,一个订单有很多装载,在表格中我打印了第一次装载的城市)
因此,由于雄辩和急切的加载已经变得很慢,我决定切换到查询生成器。但它有一些我不知道如何解决的缺陷。
查询本身已经很大了:
$orders = DB::table('orders')
->select([
//around 25 different selects
])
// nearly 10 left joins on other tables
->leftJoin(...)
// a few when-s with nested where-s, orderBy-s and so on
->when(...)
->get();
首先,我使用连接将数据表连接在一起,这在 (table)1:N(orders) 的情况下很好,但在连接 (orders)1:N(table) 时会出现问题,因为我是并没有真正尝试加入所有这些记录。对于几乎所有这些,我只需要最新或第一条记录。
我决定使用的第一个选项是 select 中的子查询,我很快意识到这是一个巨大的错误,因为它在每一行上都执行。然后我通过将子查询加入我的表找到了一个解决方案,但是查询时间太长(我只连接了一个这样的查询是 8 秒,我应该加入 6 次)
->leftJoin(DB::raw("(SELECT t1.fileable_id, t1.filename FROM files t1 INNER JOIN (SELECT fileable_id, MAX(created_at) AS max_created_at FROM files WHERE fileable_type = 'App\\Order' GROUP BY fileable_id) t2 ON t2.fileable_id = t1.fileable_id AND t2.max_created_at = t1.created_at) AS contractor_files"), 'contractor_files.fileable_id', '=', 'orders.id')
我想问有没有解决办法。如果需要,我可以发布整个查询,但它大约有 100 行长,而且总结得差不多
【问题讨论】:
-
整个查询(SQL 格式)和有关表的基数的信息将非常有用,可以更好地为您提供支持
-
通常是因为缺少索引。没有足够的数据。请为两个 Select 操作添加 Explane(例如:explane select ...)并使用每个选择的结果更新您的帖子
-
请包含正在执行的普通 SQL 查询,以及执行计划。
-
, 'contractor_files.fileable_id', '=', 'orders.id')看起来像是一个严重的语法错误。目的是什么? -
为了帮助您解决query-optimization 的问题,我们需要更多信息。请read this,然后edit您的问题。
标签: mysql sql laravel query-optimization groupwise-maximum