2017-05-15 7 views
0

Ich habe diesen Code:optimiert SQL-Abfrage PHP Phalcon

  if(($banners = $this->app->cache5min->get($key_cache)) === NULL) { 
      $find_items = array(); 
      $banners = $this->app->db->fetchAll(" 
SELECT b.id,b.active, b.richmedia, b.rich_position, b.ip_limit, 
     b.cookie_limit, b.cookie_interval, b.day_limit, b.limit_interval, 
     b.frequency, b.close_btn, b.use_geo, 
     bpl.s_x, bpl.s_y 
    FROM bs_items_places AS bp 
    LEFT JOIN bs_items AS b ON b.id = bp.item_id 
    LEFT JOIN bs_places AS bpl ON bpl.id = bp.place_id 
    WHERE b.active = 1 
     AND b.date_start < '".$dateNow."' 
     AND b.date_stop > '".$dateNow."' 
     AND bpl.active = 1 
     AND bp.place_id = {$idpl} 
     AND (IF((time_from!='00:00:00' AND time_to!='00:00:00'), 
       (time_from<='".$dateTimeNow."' 
      AND time_to >='".$dateTimeNow."'), 1) 
      ) 
    GROUP BY b.id 
    ORDER BY b.frequency DESC, b.day_limit DESC 
               "); 
      foreach($banners AS $bnr) { 
       $find_items[$bnr['id']] = $bnr; 
      } 
      $banners = $find_items; 
      $this->app->cache5min->save($key_cache,$banners); 
     } 

    //echo '<pre>'; print_r($banners); exit; 
    if(!$banners || !count($banners)) { return $this->getDefaultBanner($idpl,$x); } 

Als ich die erste Aussage entfernen, meine CPU ist gut, als ich die erste Aussage zurückkehren, meine CPU 100% und die mysql proccess gibt, wie ich Abfrage optimieren?

+0

Zuerst würden Sie es für Menschen lesbare machen. Aber ich kann bereits sagen, dass Sie keine vorbereiteten Anweisungen verwenden, was bedeuten würde, dass es auch eine potenzielle SQL-Injection-Schwachstelle gibt. –

+0

Ich brauche eine fixe CPU-Last – GodmanT

+0

Kann die Abfrage nicht analysieren, ohne zu wissen, in welcher Tabelle jede Spalte ist - insbesondere "time_from" und "time_to". –

Antwort

0

Der erste Schritt besteht darin, LEFT loszuwerden, es sei denn, Sie brauchen es. Dies kann weitere Optimierungsmöglichkeiten eröffnen.

Dieses Konstrukt ist im Wesentlichen un-optimierbar:

WHERE start < ... 
    AND end > ... 

Es gibt eine "Explosion-implodieren" -Problem. Zuerst explodiert die Anzahl der Zeilen aufgrund der JOINs, dann implodiert dies an der GROUP BY. Aber ... Inzwischen gibt es keine "Aggregate" wie COUNT() oder SUM(). So riecht das wie eine schlecht geformte Abfrage - Warum müssen Sie die GROUP BY tun? Wenn Sie doppelte Zeilen erhalten, haben Sie ein schlimmeres Problem - was passiert in den Spalten, die nicht dupliziert werden? Sie erhalten zufällige Werte. Sehen Sie, was ohne die GROUP BY passiert.

Dieser zusammengesetzte Index auf bpkann Hilfe:

INDEX(place_id, item_id) 
+0

Sie können mir eine optimierte Abfrage geben? – GodmanT

+0

@GodmanT - Ich gab Ihnen ein paar Dinge zu versuchen. Ich habe ein paar Fragen gestellt. –

Verwandte Themen