2016-07-14 2 views
0

Я в настоящее время строю запрос возвращает набор записей между датой, как это следующим образом:Symfony2 Доктрина + Twig запрос слишком долго

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 имеет некоторые ManyToOne соединение, как показано ниже:

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; 

Когда я получить записи и сделать их в веточке:

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

по телефону SERVICO .name из другого объекта, я получаю тонны невынужденных запросов в результате, чтобы отобразить имя службы, а не ее идентификатор. Мы говорим о чем-то в диапазоне записей 6k в каждом ответе.

Я хотел бы получить некоторую помощь, если это возможно, чтобы оптимизировать этот запрос, используя мой конструктор запросов или я должен переделать весь запрос более «SQL», например:

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

Любая помощь/предложения больш оценили.

EDIT 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 мс, но мой контроллер twig + берет оставшиеся 7.x секунд, так как он показывает pic https://gyazo.com/378b3553c87e04de68e87de3b6e0fc32 мой контроллер - это что-то reall у простого

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 Мое мнение, которое передается от Аякса быть вынесено как 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 'и' Service ', то для каждого «movimento», который вы получаете, в результате «сервис» будет сериализован вместе. Это означает, что если у вас есть запрос, который возвращает 100 'movimento', тогда вместе с ним будут потребоваться все объекты «service» (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)

Смежные вопросы