PHP laravel SQL优化

SQL优化的态度

--Facebook做产品的时候,注重一句话,我们不求完美,我们先把产品运行起来!


其实上边的话,我也是对自己的说的,最近比较忙,闲暇时光,总结一下过去的薄弱点,不论你做什么,写什么,你总会遇到困难,总会遇到挫折,那个时候才是你真正提高的时候,绝对......是这样,当你重复做一些事情的时候,你会慢慢厌烦,慢慢的感到不满,也许你可以认为我说的不对,但是我有必要告诉你,也有必要警醒我自己,理当磨炼,敢为天下先。


回归今天的主题:

keyword:SQL优化、态度

然而你又说了,优化谁不会呢,但是态度呢?也许就不见得了,各说纷纭,争先恐后???

我今天想要表达的很简单,你对SQL优化的态度是真诚的吗?现在都说项目经验,能不能独立完成项目,靠的是什么,靠的是你是否有信心,有能力,独立扛起你不懂但是通过你对努力,你能够解决的问题,这是担当,随着你工作、能力的提高,你会觉得,你的压力和你的薪资都会更大,那是我们成长了不少,我们对待事情的态度发生了改变,思想改变了,我们也就变了。

回归正题:对于laravel transformer结构的优化

之前的做法和想法,为提供前后台分离,我们提供接口,在架构的基础上,我们用一个后台做接口,尽量在使用同一个transformer的基础上,尽可能的复用、复用,自己写的代码是简单了,for example:

Route::get('packages/{id}','Api\PackageController@show');

//路由,写一个套餐接口

public function show($id)
    {


        $packages = $this->packageService->with(includes())->findByPackageId($id);
         
        if (!$packages) {
            return error(\Msg::PACKAGE_NOT_FOUND);
        }


        $results = fractal($packages, new PackageTransformer())
            ->parseIncludes(includes())
            ->toArray();


        return $this->response($results);
    }

//我们使用了service做服务层、repository做仓库,分页结果给fractal进行解析,使用include来添加关联的一系列

套餐相关的课程


<?php


namespace App\Transformers;
use League\Fractal\TransformerAbstract;
use App\Models\Package;

class PackageTransformer extends TransformerAbstract
{
    /**
     * A Fractal transformer.
     *
     * @return array
     */
    protected $availableIncludes = [
        'courses',
    ];


    public function transform(Package $package)
    {
        $all =  [
            'id'                 => $package->id,
            'name'               => $package->name,
            'category'           => empty($package->category['name']) ? 0 : $package->category['name'],
            'type'               => $package->type,
            'short_introduction' => $package->short_introduction,
            'detail'             => $package->detail,
            'price'              => $package->prices(),
            'discount_price'     => $package->discount_price,
            'learning_number'    => $package->number+ $package->base_number
        ];
        

    }
    public function includeCourses(Package $package)
    {
        return $this->collection($package->courses,new CourseTransformer());
    }

}
    
   

//上边就是include的使用include=courses这种参数关联的方式,耦合套餐,也许套餐关联课程结构的时候也许不需要

这个事情,之前就没有考虑到。

然后我们考虑一件事情:性能(之前听一个学者说,使用了laravel就抛弃了性能,给我造成了心理上不可磨灭的阴影,现在对我来说,都是他妈的扯淡),SQL优化

先从优化开始,先说件重要的事情:不论你是什么后台语言开发者,JAVA,PHP还是其他,必备的工具,能够可视化看到你的sql语句的调试工具,DEBUG模式一定要开启,TEST类一定要写,特别是接口测试,对于接口多的时候,你就知道好处了,你花费写接口测试是为了节省你的事情做最重要的事情,我现在使用postman总是调试接口的时候对于参数特别的时候,一个一个添加是多么无知的。


你可以看看,写了多少无知的SQL,一个接口造成性能堪忧,归根结底就是这个接口的代码写的太烂,烂到令人发指,归纳,总结牛逼之人总有牛逼之人之处,做半天工作,能够使你做三天,然后时候给你讲解时候,他倒是觉得也没有那么难,就是过程不容易直接想到,都是通过一步步优化造成的结果,你也可以。

优化之前:

$unitTestPaper = \App\Models\TestPaper::where('unit_id',$this->id)->first();

优化之后:    

$unitTestPaper = $this->testPapers->first();

下面造成关联试卷为空的操作优化后和优化之前,多查询了一百条sql,感觉有罪恶感啊,瞬间变为了

 


这就是差别,然后又开始分析,由于套餐下面有阶段,tag,阶段用with直接关联课程,所以并没有使用include,造成大量的sql涌入


public function findByPackageId($id)
    {


        $package = $this->model->where('id',$id)->first();


        $package->tags->load(['courses' => function($query) use ($id) {
            $query->where('package_id',$id);
        },'courses.teachers','courses.listImage','courses.periods.chapters.units.testPapers']);


        // $package->tags->map(function($tag){
        //      return $tag->courses;
        // })->flatten()->load('teachers');


        return $package;
    }

直接把'courses.teachers','courses.listImage','courses.periods.chapters.units.testPapers'加入查询一次就ok。必须要对其进行sql处理


经过最后的优化,只剩下了28条,其实还可以去除还有一些重复,基本上不会太大影响性能了,比之前快了不止一个档次,之前,从后台得到的数据都很慢,经过优化,速度提上去了

最后我在告诉你们一点:先完成功能,完成功能之前先思考,然后才是在有能力,有时间的情况下,尽早优化,不要推迟,一推迟,你就不想做了,记得我说的话

--时刻警醒自己



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值