使用登录器以雄辩中的查询缓慢查询



i有一个带有登录器的模型,该模型与它相关的最后一个元素(通过另一个表/模型)与之相关。它派上了个性的个人查询,但是现在我需要摘要,查询需要太长。

该模型称为设备,它具有以下访问者:

public function getPreviousDeviceAttribute()
    {
        if ($this->pos_id > 0){
            $pos = Pos::find($this->pos_id);
            $device = $pos->devices()->newPivot()->where([
                    ['device_id', '<', $this->id],
                    ['pos_id','=', $this->pos_id]
                ])->get()->sortByDesc('id')->first();
            return $device;
        } else {
            return null;
        }
    }

从控制器中,我需要查询集合的所有上一个_device。

这是查询:

$c_pendientes = Device::whereNotNull('fecha_instalacion')
                ->whereNull('fecha_reversa')
                ->where('pos_id', '>', 0)
                ->where('customer_id', 1)
                ->get();
$pendientes = $this->seriesPendientes($c_pendientes);
public function seriesPendientes($pendientes)
    {
        $count = 0;
        foreach($pendientes as $device)
        {
            $prev = $device->previous_device;
            if($prev instanceof AppDevice)
            {
                if(is_null($prev->fecha_reversa))
                {
                    $count++;
                }
            }
        }
        return $count;
    }

编辑:

属性:

设备

`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `serial` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `rotulo` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `code` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `cost_center` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `guia_recepcion` INT(11) NULL DEFAULT NULL,
    `guia_reversa` INT(11) NULL DEFAULT NULL,
    `pep` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `modified_by` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `modified_on` DATETIME NULL DEFAULT NULL,
    `fecha_recepcion` DATETIME NULL DEFAULT NULL,
    `fecha_instalacion` DATETIME NULL DEFAULT NULL,
    `fecha_reversa` DATETIME NULL DEFAULT NULL,
    `status_id` INT(10) UNSIGNED NOT NULL,
    `location_id` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci',
    `customer_id` INT(10) UNSIGNED NOT NULL,
    `str_id` INT(10) UNSIGNED NOT NULL,
    `model_id` INT(10) UNSIGNED NOT NULL,
    `pos_id` INT(11) NOT NULL,
    `user_id` INT(10) UNSIGNED NOT NULL,
    `technician_id` INT(10) UNSIGNED NOT NULL,
    `created_at` TIMESTAMP NULL DEFAULT NULL,
    `updated_at` TIMESTAMP NULL DEFAULT NULL
)

pos

CREATE TABLE `pos` (
    `id` INT(11) NOT NULL,
    `vigente` BLOB NOT NULL,
    `created_at` TIMESTAMP NULL DEFAULT NULL,
    `updated_at` TIMESTAMP NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)

关系

CREATE TABLE `devices_pos` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `device_id` INT(10) UNSIGNED NOT NULL,
    `pos_id` INT(10) UNSIGNED NOT NULL,
    `created_at` TIMESTAMP NULL DEFAULT NULL,
    `updated_at` TIMESTAMP NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)

如果要为大型集合中的每个项目调用此getter,则$pos = Pos::find($this->pos_id);行将对每个项目都有一个请求。如果尚不存在,则可以通过定义以下关系来避免它

public function pos()
{
   return $this->belongsTo(Pos::class);
}

然后急切地加载此关系(所有项目的请求):

$c_pendientes = Device::with('pos')
                ->whereNotNull('fecha_instalacion')
                ->whereNull('fecha_reversa')
                ->where('pos_id', '>', 0)
                ->where('customer_id', 1)
                ->get();

您可能应该也应该像以下方式一样:

$c_pendientes = Device::with('pos')
                ->with('pos.devices')
                ->whereNotNull('fecha_instalacion')
                ->whereNull('fecha_reversa')
                ->where('pos_id', '>', 0)
                ->where('customer_id', 1)
                ->get();

让我知道它是否有帮助。

最新更新