使用关系的雄辩查询非常慢

时间:2018-01-30 15:27:53

标签: mysql laravel eloquent database-relations

我对如何使用Eloquent Laravel上的关系表示怀疑。 我有类:Device和GeoPoint,关系为1到n。

class Device extends Model
{
    public function geoPoints()
    {
        return $this->hasMany('GeoPoint');
    }
}

class GeoPoint extends Model
{
    public function device()
    {
        return $this->belongsTo('Device');
    }
}

在不同的博客上,我读到如果我想进行一个为设备采用最新地址点的查询,我应该在类Device上建立一个新关系:

public function geoPoint()
{
     return $this->hasOne('GeoPoint', 'device_id')->latest();
}

这应该优化,但实际上这很慢。对于查询如下:

$device = Device::with('geoPoint')->find($id);

只有20.000个地理位置行,需要超过30秒。超过60,000行,它会超时。 这是正常的吗?我应该使用Eloquent ORM来生成查询吗?

2 个答案:

答案 0 :(得分:0)

我认为你应该这样做:

$device = Device::findOrFail($id);

如果找不到设备,您将获得404。

如果找到设备,您可以拨打相关型号:

$geoPoints = $device->geoPoints;

如果您只想要最新的geopoint:

$device->geoPoints->latest()->first();

答案 1 :(得分:0)

这实际上有效。我也试过了:

public function geoPoint()
{
     return $this->hasOne('GeoPoint'')->latest()->first();
}

$geoPoint = $device->geoPoint();
$device['geoPoint']= $geoPoint; // and works

但是当我尝试将Eager Loads作为:

$device = Device::with('geoPoint')->find($id); //dosent work, and give me error on undefined first() function.

我的真正目的是检索具有最新地点的所有设备,例如:

$devices = Device::with('geoPoint')->get(); // this works, but its very very slow

但我真的不想一个一个地加载它们:

foreach ($devices as $device) {
    $geoPoint = $device->geoPoint();
    $device['geoPoint'] = $geoPoint;
}

有没有办法使用Eager Loads做到这一点?