我有3张桌子
A1: name, id
A2: a_id, b_id (can be more than one a_id => b_id)
B1: id, *
我在 A2 和 A1 上使用 leftJoin 子查询,但操作非常慢(获取 10 秒) 在 B1 中,我获取数据,需要按 A2 唯一实例对 B1 进行分页并按字段进行过滤 如果没有这个查询,B1 的获取时间将少于 0.5 秒。
我找到了设置 OPTION (FORCE ORDER) 的解决方案,但它导致 Laravel 查询出错;
我正在使用
$query = $query->toSql();
$data = DB::select(DB::raw($query . " OPTION (FORCE ORDER)"));
// fetch data
$this->startCondition()
->leftJoinSub($data, 'query_data', function ($join) {
$join->on('query_data.lead_id', '=', 'table.id');
});
语法错误或访问冲突:1064 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,了解在第 1 行“OPTION (FORCE ORDER)”附近使用的正确语法
我改进了查询,添加了两列索引(a_id、b_id、created_at),但这还不够。查询速度提高 25%, 现在我花了 7.5 秒从表中获取 25 行
create index A2_index_o on A2(a_id, b_id, created_at);
我已经获取了当前页面的第一个简单分页,例如 a1=>a2,获取当前偏移量的 ids 并将其放入子查询中;
$this->prepared = array_map(fn($item) => $item->id, $prepare->items());
$subquery->whereIn('lead_id', $this->prepared)
这又为我节省了 5 秒钟。如果使用顺序进行排序,我还添加了可选过滤,但速度没有提高。
当查询运行得更快时,我的问题的主要部分得到了解决。
对于数据库查询现在看起来像
A1 data | null | null
* current offset *
A1 data | A2 data | B1 data
* end of current offset *
A1 data | null | null