Laravel本地作用域中whereNotIn()数组大小限制的解决方法
Laravel Eloquent 大数组 whereNotIn 查询问题的分片解决方案
在Laravel中使用whereIn()或whereNotIn()过滤查询结果时,当传入的数组长度超过约1500条时,查询会返回null。
试过两种替代方案但都不适用:
- 原生查询无法适配本地作用域的需求(需要基于已有查询构建);
- 设置MariaDB的
in_predicate_conversion_threshold为0属于不良实践,且MySQL不支持该变量。
最优方案是将大数组拆分为多个小数组分片处理,以下是适配本地作用域的修改代码:
public function scopeNotBlacklisted(Builder $query): void { $blacklist = Transaction::where('finalized_at', '>=', now()->subDays(365)->toDateString()) ->pluck('phonenumber') ->toArray(); // 将数组拆分为每个分片最多1000条数据(可根据实际调整安全阈值) $chunks = array_chunk($blacklist, 1000); // 用闭包组合多个分片的whereNotIn条件,逻辑与原单数组查询一致 $query->where(function ($subQuery) use ($chunks) { foreach ($chunks as $chunk) { $subQuery->whereNotIn('phonenumber', $chunk); } }); }
方案说明
array_chunk()负责将大数组拆分,这里设置每个分片最多1000条元素,你可以根据MySQL的具体限制调整为1500以内的数值;- 闭包内的循环会为每个分片添加
whereNotIn条件,最终的查询逻辑等价于原单数组的whereNotIn——即排除所有出现在黑名单中的手机号; - 这种方式完全兼容本地作用域的查询构建逻辑,同时规避了大数组导致的查询异常。
内容的提问来源于stack exchange,提问作者The Stompiest
相关产品推荐
相关产品推荐

