zoukankan      html  css  js  c++  java
  • LARAVEL WHERE HAS IN 孙龙

    环境

    • PHP >= 7
    • laravel >= 5.5

    安装

    composer require dcat/laravel-wherehasin

    简介

    Laravel的关联关系查询whereHas在日常开发中给我们带来了极大的便利,但是在主表数据量比较多的时候会有比较严重的性能问题,主要是因为whereHas用了where exists (select * ...)这种方式去查询关联数据。

    通过这个扩展包提供的whereHasIn方法,可以把语句转化为where id in (select xxx.id ...)的形式,从而提高查询性能,下面我们来做一个简单的对比:

    当主表数据量较多的情况下,where id in会有明显的性能提升;当主表数据量较少的时候,两者性能相差无几。

    主表test_users写入130002条数据,关联表test_user_profiles写入1002条数据,查询代码如下

    <?php
    /**
     * SQL:
     * 
     * select * from `test_users` where exists
     *   (
     *     select * from `test_user_profiles` 
     *     where `test_users`.`id` = `test_user_profiles`.`user_id`
     *  ) 
     * limit 10
     */
    $users1 = User::whereHas('profile')->limit(10)->get();
    
    /**
     * SQL:
     * 
     * select * from `test_users` where `test_users`.`id` in 
     *   (
     *     select `test_user_profiles`.`user_id` from `test_user_profiles` 
     *     where `test_users`.`id` = `test_user_profiles`.`user_id`
     *   ) 
     * limit 10
     */
    $users1 = User::whereHasIn('profile')->limit(10)->get();

    最终耗时如下,可以看出性能相差还是不小的,如果数据量更多一些,这个差距还会更大

    whereHas   0.50499701499939 秒
    whereHasIn 0.027166843414307 秒

    使用

    whereHasIn

    此方法已支持Laravel ORM中的所有关联关系,可以替代whereHas

    User::whereHasIn('profile')->get();
    
    User::whereHasIn('profile', function ($q) {
        $q->where('id', '>', 10);
    })->get();

    orWhereHasIn

    User::where('name', 'like', '%laravel%')->orWhereHasIn('profile')->get();

    多级关联关系

    User::whereHasIn('painters.paintings', function ($q) {
        $q->whereIn('id', [600, 601]);
    })->orderBy('id')->get()->toArray();

    需要注意的是,如果是BelongsTo类型的关联关系,使用whereHasIn时使用的不是主键,而是外键

    <?php
    
    /**
     * 这里用的是"user_id in",而不是"id in"
     * 
     * select * from `test_user_profiles` where `test_user_profiles`.`user_id` in 
     *   (
     *     select `test_users`.`id` from `test_users` where `test_user_profiles`.`user_id` = `test_users`.`id`
     *   )
     */
    $profiles = Profile::whereHasIn('user')->get();

    whereHasMorphIn

    此方法已支持Laravel ORM中的所有关联关系,可以替代whereHasMorph

    Image::whereHasMorphIn('imageable', Post::class, function ($q) {
        $q->where('id', '>', 10);
    })->get();
  • 相关阅读:
    解决phpcms图片太大撑破表格图片自适应图片按比例缩小
    CSS代码使纯英文数字自动换行
    CSS网页布局错位:CSS宽度计算
    CSS控制div宽度最大宽度/高度和最小宽度/高度
    鼠标HOVER时区块动画旋转变色的CSS3样式掩码
    记录--正则表达式
    写在前面
    ruby Mixin用法
    ruby 模块 的引入
    ruby 编写迭代器
  • 原文地址:https://www.cnblogs.com/sunlong88/p/15543686.html
Copyright © 2011-2022 走看看