摘要:哪個更快:更新/刷新實體列表,還是在每個實體上運行查詢構建器更新?Doctrine 2查詢構建器vs實體持久性能
在Doctrine ORM(版本2.3)中我們有以下情況。
我們有一個表,看起來像這樣
cow
wolf
elephant
koala
,我們想用這個表進行排序虛構農場的報告。問題在於用戶希望讓顧客訂購動物(例如考拉,大象,狼,牛)。現在有可能使用CONCAT或CASE爲DQL添加權重(例如0002wolf,0001elephant)。根據我的經驗,這要麼很難建立,當我得到它的工作結果集是一個數組,而不是一個集合。
因此,要解決這個問題,我們增加了一個「權重」字段每條記錄,然後運行選擇之前,我們給每一個與重量:
$animals = $em->getRepository('AcmeDemoBundle:Animal')->findAll();
foreach ($animals as $animal) {
if ($animal->getName() == 'koala') {
$animal->setWeight(1);
} else if ($animal->getName() == 'elephant') {
$animal->setWeight(2);
}
// etc
$em->persist($animal);
}
$em->flush();
$query = $em->createQuery(
'SELECT c FROM AcmeDemoBundle:Animal c ORDER BY c.weight'
);
這完美的作品。爲了避免競爭條件下,我們加入這一個事務塊裏面:
$em->getConnection()->beginTransaction();
// code from above
$em->getConnection()->rollback();
這是很多更強大的,因爲它處理多個用戶生成相同的報告。或者實體進行加權像這樣:
$em->getConnection()->beginTransaction();
$qb = $em->createQueryBuilder();
$q = $qb->update('AcmeDemoBundle:Animal', 'c')
->set('c.weight', $qb->expr()->literal(1))
->where('c.name = ?1')
->setParameter(1, 'koala')
->getQuery();
$p = $q->execute();
$qb = $em->createQueryBuilder();
$q = $qb->update('AcmeDemoBundle:Animal', 'c')
->set('c.weight', $qb->expr()->literal(2))
->where('c.name = ?1')
->setParameter(1, 'elephant')
->getQuery();
$p = $q->execute();
// etc
$query = $em->createQuery(
'SELECT c FROM AcmeDemoBundle:Animal c ORDER BY c.weight'
);
$em->getConnection()->rollback();
問題:
1),其中的兩個例子將有更好的表現?
2)是否有第三種或更好的方法來記住我們需要一個集合作爲結果?
請記住,這只是一個示例 - 對內存中的結果集進行排序不是一個選項,它必須在數據庫級別上完成 - 真正的語句是具有5個orderbys的10個表連接。
感謝您的回答。在我們使用Symfony 2.1時,無論如何,我們都會在開發者分析器中獲得SQL時間。客戶無論如何都決定他們需要querybuilder路由。更新/回滾方法完美。 – mogoman
好吧,無論如何你都歡迎:) – manix