2016-07-14 13 views
0

我目前正在建設一個查詢的停留日期間返回一組記錄,因爲它遵循:Symfony2的教義+分支查詢時間太長

public function findBetweenDates(\Datetime $date1,\Datetime $date2) 
{ 
     $date1=$date1->setTime(07,00,00); 
     date_modify($date2,'+1 day'); 
     $date2->setTime(06,59,00); 
     $qb = $this->getEntityManager()->createQueryBuilder() 
      ->select('e') 
      ->from("AppBundle:Movimento","e") 
      ->andWhere('e.pesagem1 BETWEEN :from AND :to') 
      ->setParameter('from', $date1) 
      ->setParameter('to', $date2) 
      ->orderBy('e.id','DESC') 

     ; 
     $result = $qb->getQuery()->getResult(); 
     return $result; 
    } 

類MOVIMENTO有一些多對一的連接,如下圖所示:

class Movimento 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="Service") 
    * @ORM\JoinColumn(name="service", referencedColumnName="id") 
    **/ 
    private $service; 

,當我得到記錄,並使其在樹枝:通過調用servico

{% for item in items %} 
    <tr> 
     <td>{{ item.id }} </td> 
     <td>{{ item.service.name }}</td> 
//#MORE CODE BELOW // 

.name從另一個實體我得到大量不想要的查詢作爲結果顯示服務的名稱,而不是它的ID。 我們在每個迴應中都在討論6k範圍內的記錄。

我想一些幫助,如果可能的話用我的查詢生成器來優化這個查詢或者我應該重拍了「SQL」的例子整個查詢更多:

Select a.name, b.id 
From service as a, movimento as b 
Between bla bla bla 

任何幫助/建議是大大讚賞。

編輯1 我改變了我的查詢生成器閱讀這篇文章Symfony 2/Doctrine: How to lower the num of queries without losing the benefit of ORM?

我沒減少175個查詢到一個單一的一個

$qb = $this->createQueryBuilder('e') 
      ->addSelect('service')->join('e.service','service') 
      ->addSelect('motorista')->join('e.motorista','motorista') 
      ->addSelect('residuo')->join('e.residuo','residuo') 
      // ->from("AppBundle:Movimento","e") 
      ->andWhere('e.pesagem1 BETWEEN :from AND :to') 
      ->setParameter('from', $date1) 
      ->setParameter('to', $date2) 
      ->orderBy('e.id','DESC') 

但仍頁花費大約8秒鐘的加載後(它的6900條記錄)和檢查性能後,我的新查詢的響應時間是177.79毫秒,但我的樹枝+控制器正在採取剩餘的7.x秒,因爲它顯示圖片https://gyazo.com/378b3553c87e04de68e87de3b6e0fc32 我的控制器是reall y簡單

public function getMovimentosAction(Request $request) 
    { 

     $startDate = $request->request->get('startDate'); 
     $endDate = $request->request->get('endDate'); 

     if (empty($startDate)) 
      $startDate = date("Y-m-d") ; 
     if (empty($endDate)) 
      $endDate = date("Y-m-d"); 

     $em=$this->getDoctrine()->getRepository('AppBundle:Movimento'); 
     $dados=$em->findBetweenDates(new \DateTime($startDate),new \DateTime($endDate)); 

     return $this->render('AppBundle:Movimentos:logtable-movimento.html.twig', array(
      'items' => $dados 
     )); 
    } 

和我的樹枝只是遍歷行並顯示它們在桌子上,因爲我給了上面的部分示例。

任何幫助/建議將不勝感激。

EDIT2 我是通過AJAX傳遞你有MOVIMENTO之間的」連接到,只要呈現爲datatable.js

<table id="example" class="table table-striped table-bordered table-hover" cellspacing="0" width="100%"> 
    <thead class="dataTableHeader"> 
    <tr> 
     <th>Talão</th> 
     <th>Nº Talão</th> 
     <th>Motorista</th> 
     <th>Residuo</th> 
     <th>Serviço</th> 
     <th>Matricula</th> 
     <th>1º Pesagem</th> 
     <th>Peso Liquido</th> 
     <th>Fluxo</th> 
     <th>Circuito</th> 
     <th>Verificado</th> 
     <th></th> 
    </tr> 
    </thead> 
    <tfoot class="dataTableHeader"> 
    <tr> 
     <th>Talão</th> 
     <th>Nº Talão</th> 
     <th>Motorista</th> 
     <th>Residuo</th> 
     <th>Serviço</th> 
     <th>Matricula</th> 
     <th>1º Pesagem</th> 
     <th>Liquido</th> 
     <th>Fluxo</th> 
     <th>Circuito</th> 
     <th>Verificado</th> 
     <th></th> 
    </tr> 
    </tfoot> 
    <tbody> 
    {% for item in items %} 
    <tr> 
     <td align="center"><a href="{{ path("_movimento_generate_pdf",{ id: item.id }) }}"> <i class="fa fa-print fa-2x" aria-hidden="true"></i> 
      </a></td> 
     <td>{{ item.id }} <a><i class="fa fa-eye" title="Visualizar Movimento" aria-hidden="true"></i></a> 
     </td> 
     <td>{{ item.motorista.idFuncionario }} - {{ item.motorista.nome }}</td> 
     <td>{{ item.residuo.nome }}</td> 
     <td>{{ item.servico.nome }}</td> 
     <td>{{ item.matricula }}</td> 
     <td>{{ item.pesagem1|date('Y-m-d h:m') }}</td> 
     <td>{{ item.liquido }} kg</td> 
     <td>{% if item.tipoMovimento == 1 %} Entrada {% else %} Saida {% endif %}</td> 
     <td>{{ item.circuito.code | default(" ") }}</td> 
     <td class="text-center">{% if item.enable==1 %} 
       <span style="color: transparent">&nbsp;</span> 
       <i class="fa fa-circle" aria-hidden="true" style="color: green"></i> 
      {% else %} 

       <i class="fa fa-times" aria-hidden="true" style="color: red;"></i> 
      {% endif %} 
     </td> 
     <td class="text-center"> 
      <a class="btn btn-default" href="{{ path('_movimentos_edit',{ 'id' : item.id}) }}"> 
       <i class="fa fa-cog" title="Editar" aria-hidden="true"></i> 
       <span class="sr-only">Settings</span> 
      </a> 
     </td> 
    </tr> 

    {% endfor %} 


    </tbody> 
</table> 

,並在我的HTML

$("#submitButtonQuery").click(function(event){ 
      event.preventDefault(); 
      var l = Ladda.create(this); 
      l.toggle(); 
      $.post("/movimentos/getList", 
       $("#formAjaxify").serialize()) 
       .done(function(data) 
       { 
        $('#example').remove(); 

        $("#tabelaLog").html(data); 
        oTable=$('#example').DataTable(
         { 
          "scrollX": true, 
          responsive: true, 

          "language": { 
           "url": "http://cdn.datatables.net/plug-ins/1.10.11/i18n/Portuguese.json" 
          } 
         } 
        ); 
        oTable.order([ 0, 'desc' ]) 
         .draw(); 
     }) 
     .always(function(){ 
      l.toggle()}) 
    ; 
}); 
+0

你可以請你張貼完整的樹枝模板嗎? –

+0

你真的需要一次渲染**所有**記錄嗎?你不能分頁結果嗎? – dlondero

+0

那麼,關於立即導入所有記錄的事情是,它可以更容易地使用數據表進行搜索,並且還可以導出爲pdf/csv功能。 – Noize

回答

0

視圖'和'服務',然後爲每個'movimento',你會得到一個'服務'將被序列化在一起。這意味着如果你有一個返回100'movimento'的查詢,那麼所有的'服務'對象(100)都會被要求提取。

如果您不想將服務作爲每個項目(AKA item.service.blahblah)中的對象,那麼您需要有一個更直接的查詢。

,如果你與查詢生成器做到這一點,那麼你將需要類似:

$repository = $this->getDoctrine() 
     ->getRepository('YourownBundle:Movimento'); //the main repo from which to get data 

    $query = $repository->createQueryBuilder('m') // query builder on repo 
     ->join('m.service', 's') // join the second object to select from 
     ->select('m.id') // select everything from m objet 
     ->addSelect('s.name') // select everything from service (s) object 
     ->where('e.pesagem1 BETWEEN :from AND :to') 
     ->setParameter('from', $date1) 
     ->setParameter('to', $date2) 
     ->orderBy('e.id','DESC') 

你的代碼的其餘部分應該是因爲你擁有它......但你沒有一個序列化對象,但只有你所做的選擇(例如,m.id,s.name)