• Stars
    star
    249
  • Rank 162,987 (Top 4 %)
  • Language
    PHP
  • License
    MIT License
  • Created over 4 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Laravel wherehasin是一个可以提升Laravel ORM关联关系查询性能的扩展包,可以替代Laravel ORM中的whereHas以及whereHasMorphIn查询方法。

LARAVEL WHERE HAS IN

Build Status StyleCI

Laravel wherehasin是一个可以提升Laravel ORM关联关系查询性能的扩展包,可以替代Laravel ORM中的whereHas以及whereHasMorphIn查询方法。

环境

  • 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();

License

The MIT License (MIT).

More Repositories

1

dcat-admin

🔥 基于 Laravel 的后台系统构建工具 (Laravel Admin),使用很少的代码快速构建一个功能完善的高颜值后台系统,内置丰富的后台常用组件,开箱即用,让开发者告别冗杂的HTML代码
PHP
3,860
star
2

dcat-admin-demo

PHP
275
star
3

easy-excel

🚀 快速读写Excel文件,简单高效
PHP
148
star
4

swoft-admin

此项目已废弃
PHP
70
star
5

dcat-page

📝 简单易用的静态站点构建工具(PHP版)
JavaScript
48
star
6

laravel-softdeletes

Laravel softdeletes是一个用于替代Laravel内置软删除功能的扩展包,可以把软删数据存储到独立的数据表中,从而不影响原始表字段增加唯一索引,且可以起到提升性能的作用。
PHP
37
star
7

laravel-log-viewer

Dcat Log Viewer是一个Laravel日志查看工具,支持大文件日志的查看、搜索以及多层级目录功能。
PHP
30
star
8

dcat-admin-ueditor

Dcat Admin扩展 - 百度在线编辑器
JavaScript
19
star
9

swoft-admin-auto

此项目已废弃
JavaScript
8
star
10

php-utils

日常使用工具集
PHP
8
star
11

dcat-admin-gank

PHP
6
star
12

swoft-admin-demo

swoft-admin demo源码
JavaScript
4
star
13

swoft-blade

Lavarel blade模板引擎移植
PHP
3
star
14

jquery-terminal-emulator

JQuery版命令窗模拟器
JavaScript
3
star
15

neta-server

基于swoole的server端快速开发框架
PHP
3
star
16

swoft-crontab-task

毫秒级定时任务管理工具,支持多节点可视化管理
2
star
17

framework-lxh

PHP 轻量级web快速开发框架
JavaScript
2
star
18

lldca-support

PHP
2
star
19

lxh-blade

轻量级js模板引擎
JavaScript
1
star