Вопросы, связанные с производительностью Phalcon

Я создаю REST API для вывода конечных точек / проектов. Я создал две модели:

Проекты:

class Projects extends BaseModel { public function initialize() { $this->hasMany('id', 'Participants', 'projectId'); } } 

Участники:

 class Participants extends BaseModel { public function initialize() { $this->belongsTo('projectId', 'Projects', 'id'); } } 

Допустим, у меня есть 10 проектов: (1 запрос)

 $results = Projects::find(); 

Я просматриваю все 10 из них, но хочу, чтобы все участники тоже:

 foreach($results as $result) { echo $result->participants; // 1 query } 

Поэтому в конце цикла Phalcon сделал дополнительный запрос для каждого проекта.

Эти запросы были сделаны путем доступа к участникам $ result->, итерации более 10 проектов:

 SELECT IF(COUNT(*)>0, 1 , 0) FROM `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_NAME`='projects' DESCRIBE `projects` SELECT `projects`.`id`, `projects`.`title`, `projects`.`client`, `projects`.`color`, `projects`.`start_date`, `projects`.`end_date`, `projects`.`notes`, `projects`.`stateId`, `projects`.`created_at`, `projects`.`updated_at` FROM `projects` SELECT IF(COUNT(*)>0, 1 , 0) FROM `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_NAME`='project_participants' DESCRIBE `project_participants` SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 SELECT `project_participants`.`id`, `project_participants`.`project_id`, `project_participants`.`user_id`, `project_participants`.`user_role_id`, `project_participants`.`user_state_id`, `project_participants`.`updated_at`, `project_participants`.`created_at` FROM `project_participants` WHERE `project_participants`.`project_id` = :0 

Вопрос

Есть ли способ запросить отношения перед рукой, поэтому это будет один запрос. Когда я использую построитель запросов, предоставленный Phalcon, я не могу получить доступ к -> участникам таким же образом.

редактировать

Я закончил с помощью Query Builder, namespacing всех столбцов

 $builder = $modelsManager->createBuilder(); $builder->columns($columns) ->from('Projects') ->leftJoin('Participants') ->getQuery() ->execute(); 

Столбцы:

 Projects.id as projects_id ... Participants.id as participants_id Participants.projectId as participants_projectId 

Поскольку доступ -> участников к результату, созданному Query Builder, также вызывал дополнительные запросы.

Для доступа -> участников так же, как с помощью QueryBuilder, вам нужно будет создать соединение в Query.

Пример кода может быть примерно таким:

 $queryBuilder = $this->getDI()->getModelsManager() ->createBuilder() ->columns(['p.id','participants.*']) ->addFrom('Entity\Projects', 'p') ->leftJoin('Entity\Participants', 'participants.projectId = p.id', 'participants') ->groupBy('p.id, participants.id') ->orderBy('p.id ASC'); $resultSet = $queryBuilder->getQuery()->execute(); 

groupBy() используется здесь, чтобы сделать результат, возможно, многомерным.

Такой запрос (проверенный в PgSQL) заставил Phalcon создать некоторые последующие объекты участников ResultSet pi внутри Resultsets для проектов p .

Вы все еще можете перебирать его, используя foreach() но в конце концов, я не уверен, что это уменьшило количество окончательных запросов .

Fireing $result = $resultSet->toArray() сделал $result['pi'] остался как Resultset, поэтому вы должны быть осторожны в этом. Вы можете заставить его сбрасывать как массивы, определяя точные столбцы в параметрах columns() . У этого есть недостаток – вы больше не будете получать прибыль от groupBy() , по крайней мере, на Phalcon 1.3.2 и PHP 5.5.3, которые работают здесь.

Существует большая библиотека для активной загрузки на фалкон.

stibiumz phalcon нетерпевая загрузка

Эта библиотека решает N + 1 запросов для отношений. Он уже включен в инкубатор фалкона. Я использую его уже на производстве.

Он создает запрос с использованием предложения IN и заполняет модели результатами.

У многих есть:

 SELECT * FROM main SELECT * FROM related WHERE x.id IN (results from the previous resultset)