【问题标题】:Laravel Eloquent: Query with whereIn and orWhere very slowLaravel Eloquent:使用 whereIn 和 orWhere 查询非常慢
【发布时间】:2018-01-30 23:43:37
【问题描述】:

我正在进行当前查询以检索具有他所有关系的“OV”对象。我最近在masterswireless 中添加了添加过滤器的功能,但是它引入了很长的延迟。

我使用 whereIn 和 orWhere 关闭的方式是否有错误或问题?

注意:devicesArrayOnlyLKUAToZero var 是一个包含 macAddress 列表的数组

$data = Ov::with([
    'ovLicenses',
    'masters'=> function ($query) use ($devicesArrayOnlyLKUAToZero) {
        $query->whereIn('macAddress', $devicesArrayOnlyLKUAToZero)->orWhere('lastKnownUpAt','!=', '0');
    },
    'masters.licenses',
    'masters.equipment',
    'masters.slaveEquipments.equipment',
    'wireless'=> function ($query) use ($devicesArrayOnlyLKUAToZero) {
        $query->whereIn('macAddress', $devicesArrayOnlyLKUAToZero)->orWhere('lastKnownUpAt','!=', '0');
    },
    'wireless.licenses',
    'wireless.equipment'
])->where('ovId', '=', $ovId)->get();

使用 debugBar Laravel 进行调试,例如,我对无线执行以下请求:

select * from `wirelessequipments` where `wirelessequipments`.`id_ov_foreign_key` in ('38') and `macAddress` in ('e8:e7:32:c1:e6:48', 'e8:e7:32:bc:b0:94', 'e8:e7:32:e4:8e:68', 'e8:e7:32:bc:a7:70', '00:e0:b1:fe:ef:a5', 'e8:e7:32:bc:a7:a4', '2c:fa:a2:10:79:74', 'e8:e7:32:b9:6d:1d', '00:e0:b1:ee:58:2d', '00:e0:b1:9d:2c:44', '00:e0:b1:b5:e6:00', '00:e0:b1:72:34:86', '00:e0:b1:fe:ee:8d', '00:e0:b1:79:53:52', '00:e0:b1:fe:f0:bd', '00:e0:b1:75:fa:8a', 'e8:e7:32:98:80:22', '00:e0:b1:75:00:8a') or `lastKnownUpAt` <> '0'

这个请求似乎是错误的,因为它返回了一组错误的结果。

【问题讨论】:

  • 您是否以某种方式调试查询? (尝试debugbar)。调试(或理解)Eloquent ORM 在幕后做什么可以帮助你很多。您最终可能会编写自己的快速查询,或者您会以某种方式优化(在应用层缓存)结果。您需要一次获取所有数据吗?尝试限制、选择等。
  • $devicesArrayOnlyLKUAToZero 数组有多大?
  • @RossWilson 大约 40 行
  • macAddresslastKnownUpAt 的索引吗?
  • 40 行不应该产生那么大的延迟。首先,macAddress 使用什么字段类型?另外,你在列上有索引吗?

标签: laravel laravel-5 orm eloquent where-in


【解决方案1】:

将 whereIn 转换为普通连接将解决问题。 whereIn 仅用于有限的数据范围(第二个参数)。 仅在整数的情况下替代 whereIn 是 whereIntegerInRaw 真的非常快。

【讨论】:

    【解决方案2】:

    如果您使用 Laravel 调试器,您会看到 laravel 预加载运行两个查询,而您可以使用 join 执行此操作,这比 Laravel 的预加载快得多。

    希望这会有所帮助。

    【讨论】:

    • 使用 Laravel 调试器,我在雄辩的请求中看到每个条目的多个请求。请查看我的更新
    猜你喜欢
    • 1970-01-01
    • 2021-02-11
    • 2015-02-22
    • 2020-01-01
    • 2018-02-27
    • 2017-07-30
    • 1970-01-01
    • 2017-11-17
    • 2021-11-06
    相关资源
    最近更新 更多