平时的业务中,MySQL 中的 in 查询方式通常用来避免 N+1 查询的情况,Laravel 框架的 Eloquent ORM 提供了 whereIn 方法来构造 SQL 语法中的 in 查询。

有一次项目中出现了需要使用 in 查询获取流程信息的情况,例如:

$stepIds = [9, 5, 3, 7, 8];
$steps = Step::whereIn('id', $stepIds)->get()->toArray();

结果为:

// print_r($steps)
[
    ['id' => 3, 'title' => 'step3'],
    ['id' => 5, 'title' => 'step5'],
    ['id' => 7, 'title' => 'step7'],
    ['id' => 8, 'title' => 'step8'],
    ['id' => 9, 'title' => 'step9']
]

显然使用 in 查询返回的结果对 id 字段自动进行了排序!

查询资料后了解到,MySQL 在处理 in 查询时候,并不是类似 join 的方式进行逐行地遍历对比(显然这种办法十分低效),MySQL 的优化器首先会对需要 in 查询的一系列数据进行排序,然后根据排序结果的最大值和最小值进行范围匹配,然后从匹配到的行中逐行对比来获取需要的行,这样一来如果 in 查询的列上存在索引的话,范围匹配的时候索引会被高效使用起来,相比起逐行逐行地查询,速度要快了不止一个数量级(顿悟)!