Doctrine entity remove vs delete query, сравнение производительности

При использовании доктрины я заметил, что для удаления объекта мне нужно получить этот объект по заданному параметру (имя, идентификатор и т. Д.), А затем вызвать метод удаления. С другой стороны, в запросе я могу просто выполнить запрос на удаление.

Таким образом, похоже, использование стиля ORM требует двух операций, а общая операция sql требует одной операции. Вот почему, я немного запутываюсь, следует ли нам использовать операцию удаления (или обновления) в ORM? Разве это не хуже в производительности? Или есть что-то еще, что мне не хватает? Можно ли это сделать любым способом в стиле ORM?

В Doctrine2 вы можете вызвать delete на прокси-объекте, который не загружен из базы данных. Просто создайте «фиктивный» объект, что-то вроде:

$user = $em->getPartialReference('model\User', array('id' => $id)); $em->remove($user); 

Он не требует первоначального запроса, но я не совсем уверен, что Doctrine все еще делает это внутренне на fush . Я не вижу его в SqlLog.

Просто чтобы добавить, я думаю, что это ожидаемое поведение любого приличного ORM. Он касается объектов и отношений. Он должен знать, что перед удалением чего-то существует. ORM – это не просто генератор запросов . Как правило, собственный запрос всегда будет быстрее в любом ORM. Любая ORM добавляет слой абстракции, и для ее выполнения требуется некоторое время. Это типичный компромисс, вы получаете некоторые причудливые функции и чистый код, но немного теряете производительность.

РЕДАКТИРОВАТЬ:

Я рад, что это сработало для вас. Фактически я наткнулся на другую проблему, которая заставила меня понять, что прокси и частичные объекты на самом деле не то же самое. Частичные объекты представляют экземпляр реального класса модели и заполняют его необходимыми значениями. После инициализации частичного объекта lazy-load больше не работает на нем. Например, если вы делаете частичный объект только с идентификатором и хотите удалить только в том случае, если другое поле объекта удовлетворяет некоторому условию, оно не будет работать, потому что это другое поле всегда будет нулевым.

С другой стороны, прокси-серверы работают с ленивой загрузкой и не разделяют проблем, которые имеют частичные объекты. Поэтому я настоятельно рекомендую не использовать метод getPartialReference , вместо этого вы можете сделать что-то вроде:

 $user = $em->getReference('model\User', $id); $em->remove($user); 

Метод getReference возвращает объект, если он уже загружен, или прокси-сервер, если это не так. Прокси-сервер может ленить все остальные значения, если / когда они вам понадобятся. Что касается вашего примера, они будут вести себя точно так же, но прокси-серверы, безусловно, лучший способ пойти.

Готово! для меня это сработало, как эта строка добавления 3:

 $user = $em->getReference('model\User', $id); $em->remove($user); $em->flush();