【PHP】關於fastadmin框架中使用with進行連表查詢時setEagerlyType欄位的理解

我恨bug發表於2024-07-09

前言

FastAdmin是我第一個接觸的後臺管理系統框架。FastAdmin是一款開源且免費商用的後臺開發框架,它基於ThinkPHP和Bootstrap兩大主流技術構建的極速後臺開發框架,它有著非常完善且強大的功能和便捷的開發體驗,使我逐漸喜歡上了它。

什麼是setEagerlyType?

1.迴歸正題,什麼是setEagerlyType?

setEagerlyType是fastadmin在使用關聯查詢時提供的配置欄位,為設定預載入方式。根據官方文件描述,在V5.0.4+版本開始一對一關聯預載入支援兩種方式:setEagerlyType(0) 是JOIN方式(一次查詢) setEagerlyType(1)是IN方式(兩次查詢)。

2.例子

2.1 當使用join的方式(setEagerlyType(0))

在model層對應的model檔案加入該函式 $this->belongsTo(被關聯表,外來鍵, 主鍵, [], 'LEFT')->setEagerlyType(關聯模式 0/1 );

public function product()
    {
        return $this->belongsTo('app\common\model\xxxx\xxxx',  'PID', 'PID', [], 'LEFT')->setEagerlyType(0);
    }
//此處返回的是一個二維陣列
$List=$this->xxxxModel->with('product')->page($page, $pageSize)->select();

因為返回的是一個二維陣列所以可以使用關聯表中的欄位product.name='xxx'

$whiskybaseList=$this->xxxxxModel->with('whiskybaseProduct')->where('product.name','xxx')->page($page, $pageSize)->select();

當然,如果需要關聯多張表也可以把with中的引數寫成陣列形式

$whiskybaseList=$this-xxxxModel->with(['pProduct','xxxxxxxxx','xxxxx'])->page($page, $pageSize)->select();

2.2 當使用In的方式(setEagerlyType(1))

public function product()
    {
        return $this->belongsTo('app\common\model\xxxx\xxxx',  'PID', 'PID', [], 'LEFT')->setEagerlyType(1);
    }
//此處返回的是一個一維陣列
$whiskybaseList=$this->xxxxModel->with('product')->page($page, $pageSize)->select();

因為使用的是IN模式,返回的是一個一維陣列所以無法使用關聯表中的欄位product.name='xxx'

$whiskybaseList=$this->xxxxModel->with('product')->where('product.name','xxx')->page($page, $pageSize)->select();

使用IN模式呼叫關聯表的欄位是查不到關聯資料的
image

3.請求速度

通常情況下使用 JOIN 操作比 IN 子查詢更快。這是因為資料庫最佳化器在執行查詢計劃時能夠更有效地處理 JOIN 操作,而且 JOIN 操作可以使用索引來加速資料檢索。

4.疑問

我前段時間使用關聯表的時候就遇到了一個問題,很奇怪,希望知道的大佬評論區指點一下!

問題!

就是公司要求我爬取國外的一個網站的資料,匯入平臺作為借鑑,然後爬取並清理完資料以後,一張是產品表,裡面有一個PID對應著產品詳情表的PID,所以我在做查詢時我需要關聯詳情表的PID獲取詳情,資料的話產品表與詳情表都各15w條資料,而且我將PID設定為索引了已經,然而當我在做分頁查詢時,使用的是join查詢,查詢100s都沒出結果,但是我使用IN查詢,0.1s既有結果,這又是為什麼?程式碼如下

model層

public function whiskybaseProduct()
    {
        return $this->belongsTo('app\common\model\Whiskybase\Whiskybase',  'PID', 'PID', [], 'LEFT')->setEagerlyType(1);
    }

業務層

//因為查詢的資料欄位基本大部分要用到,所以也沒有使用field去指定返回什麼欄位,雖然這樣能快一丟丟
$whiskybaseList=$this->WhiskybasedetailModel->where('title_zh', 'LIKE', '%' . $keyWord . '%')->with('whiskybaseProduct')->page($page, $pageSize)->order($sort, 'asc')->select();

業務層不變,model層setEagerlyType(1)改為IN方式setEagerlyType(0),查詢速度從0.1s變為100s+
如果有大佬知道,請評論區指導一下~謝謝!

上述為個人整理內容,水平有限,如有錯誤之處,望各位園友不吝賜教!如果覺得不錯,請點選推薦和關注!謝謝~๑•́₃•̀๑ [鮮花][鮮花][鮮花]

相關文章