One possible solution to optimize this code is to use eager loading to reduce the number of database queries. This can be done by adding the "with" method to the query, specifying the related models to be loaded. For example, if the "telefonos" and "propiedades" models are related to the "clientes" model, the query can be modified as follows:
public function scopeBuscadorClientes($query, $buscar, $sucursal, $tipo_prop, $frecuencia, $fuente, $ult_visita)
{
return $this->with(['telefonos', 'propiedades.telefonos', 'propiedades.visitas'])
->where('nombre', 'like', '%'.$buscar.'%')
->orWhere('apellido', 'like', '%'.$buscar.'%')
->orWhere('email', 'like', '%'.$buscar.'%')
->orWhere('id_secundario', 'like', '%'.$buscar.'%')
->orWhereHas('telefonos', function($query) use ($buscar){
$query->where('numero', 'like', '%'.$buscar.'%');
})
->orWhereHas('propiedades.telefonos', function($query) use ($buscar){
$query->where('numero', 'like', '%'.$buscar.'%');
})
->orWhereHas('propiedades', function($query) use ($buscar){
$$query->where('direccion', 'like', '%'.$buscar.'%');
})
->when($sucursal, function ($query) use ($sucursal) {
return $query->whereHas('propiedades', function ($q) use ($sucursal) {
$q->where('sucursal_id', $sucursal);
});
})
->when($tipo_prop, function ($query) use ($tipo_prop) {
return $query->whereHas('propiedades', function ($q) use ($tipo_prop) {
$q->where('tipo_id', $tipo_prop);
});
})
->when($frecuencia, function ($query) use ($frecuencia) {
return $query->whereHas('propiedades', function ($q) use ($frecuencia) {
$q->where('frecuencia_id', $frecuencia);
});
})
->when($fuente, function ($query) use ($fuente) {
return $query->where('fuente_id', $fuente);
})
->when($ult_visita, function ($query) use ($ult_visita) {
return $query->whereHas('propiedades', function ($q) use ($ult_visita) {
$q->whereDoesntHave('visitas', function ($q) use ($ult_visita) {
$q->whereBetween('fecha', [$ult_visita, Carbon::now()]);
});
});
});
}
This will load all the related "telefonos", "propiedades.telefonos", and "propiedades.visitas" models in a single query, instead of making separate queries for each related model. This can significantly improve the performance of the search function.
Another possible optimization is to use indexing on the database tables to speed up the search queries. This can be done by adding indexes to the columns that are frequently searched or filtered. For example, if the "nombre", "apellido", "email", and "id_secundario" columns are frequently searched, they can be indexed as follows:
ALTER TABLE clientes ADD INDEX nombre_idx (nombre);
ALTER TABLE clientes ADD INDEX apellido_idx (apellido);
ALTER TABLE clientes ADD INDEX email_idx (email);
ALTER TABLE clientes ADD INDEX id_secundario_idx (id_secundario);
This will create indexes on the specified columns, which can speed up the search queries that use these columns. However, adding too many indexes can also slow down the database performance, so it's important to only add indexes that are necessary for the search queries.