【发布时间】:2020-03-22 02:25:18
【问题描述】:
我有一个导出功能,我想使用给定的 ID 查询和导出。我找到了使用skip() 和take() 进行查询的解决方案,但是现在whereIn('id', $ids) 给了我错误,因为它现在有85k 条记录。
PDOException: SQLSTATE[HY000]: 一般错误: 1390 Prepared statement contains too many placeholder
我使用的解决方案是:
public function handle() {
$max = 5000;
$total = $this->givenIds->count();
$pages = ceil($total / $max);
for ($i = 1; $i < ($pages + 1); $i++) {
$offset = (($i - 1) * $max);
$start = ($offset == 0 ? 0 : ($offset + 1));
MyModel::whereIn('id', $givenIds)
->orderBy('created_at', 'desc')
->skip($start)
->take($max)
->get();
// $this->generateTempCsv();
}
// $this->combineTempCSVs()
}
这在没有瓶颈的情况下运行良好 - 直到出现太多占位符错误。现在我收到了这个错误,我尝试了:
$query = MyModel::orderBy('created_at', 'desc')
foreach ($this->givenIds->chunk(2000) as $i => $chunk) {
if ($i == 0) {
$query = $query->whereIn('id', $chunk);
} else {
$query = $query->orWhereIn('id', $chunk);
}
}
这给出了同样的错误。
如果我想使用 givenIds 进行查询,但仍想保留“orderBy - created_at”而不出现瓶颈,我该怎么办?
givenIds来自Controller(如上代码为Job):
$givenIds = MyModel::select('id', 'created_at')
->where(function($q) use ($dateRange, $queries) {
$this->applyQueryFilters($q, $queries, $dateRange);
})
->orderBy('created_at', 'desc')
->pluck('id');
Exporter::dispatch($givenIds)->onQueue('export');
PS:我使用$givenIds 的原因是因为有过滤器,首先我在应用过滤器后获得相关的ID,然后将$givenIds 传递给工作。获取$givenIds 时是否需要按 id 排序并取决于那里的顺序?
【问题讨论】:
-
如何获取数组内容??如果您通过选择构建数组,则不需要 IN 子句
-
我添加了一个编辑,显示负责它的控制器
-
我不在lavavel,所以如果你需要,我可以建议一个基于纯sql的解决方案
-
你显然应该使用 JOIN
-
@scaisEdge 谢谢,但我想知道 Laravel 的查询构建器方式。 - @YourCommonSense 你会如何使用 Larave 查询生成器来做呢?
标签: mysql laravel laravel-query-builder