2016-12-18 6 views
0

Ich habe ein Problem mit einer einfachen Abfrage zu meiner MySQL-Datenbank mit den CodeIgniter3-Bibliotheken. Ich stehe vor dem Problem, den Engpass zu finden und würde gerne Ihre Meinung hören.CodeIgniter3 und result_array() Zeitüberschreitung

Technische Daten:

  • PHP 5.4
  • CodeIgniter 3.1.2
  • MySQL 5.1.73 (via /var/lib/mysql.sock)

Tabelle "Benachrichtigungen":

+-------------+--------------+------+-----+------------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+--------------+------+-----+------------+----------------+ 
| id   | int(11)  | NO | PRI | NULL  | auto_increment | 
| receiver_id | int(11)  | NO | MUL | 0   |    | 
| content  | varchar(254) | NO |  | NULL  |    | 
| created  | varchar(10) | NO |  | 1000000000 |    | 
| seen  | set('0','1') | NO |  | 0   |    | 
+-------------+--------------+------+-----+------------+----------------+ 
5 rows in set (0.01 sec) 

direkte Abfrage aus mysql:

mysql> select * from notifications order by created desc limit 100; 
... 
... 
100 rows in set (0.01 sec) 

Abfrage mit CodeIgniter:

// Load User's Notifications 
public function LoadNotifications($UserID) 
{ 
    // Load Replies 
    $sql   = "SELECT id, content, created, seen FROM notifications WHERE receiver_id=$UserID ORDER BY created DESC LIMIT 100"; 
    $query   = $this->db->query($sql); 
    if($query->num_rows() == 0) return '0'; 
    $results  = $query->result_array(); 
    return $results; 
} 

Meine Beobachtungen und lange Zeit versucht, einen Grund zu finden, ergab, dass diese Linie Ursachen das Problem:

$results  = $query->result_array(); 

CodeIgniter bietet eine weitere Möglichkeit, die Ergebnisse als ein Objekt zu erhalten, anstatt mit diesem Befehl ist:

$results  = $query->result(); 

Wie Sie vielleicht schon erraten haben, ich das gleiche Ergebnis mit PHP bekommen alle CPU essen und nginx Verbindung Ablaufen mit einem HTTP/1,1 504

  • ich versucht habe Mysql_Slow_Queries einzuloggen, wurden keine gefunden.
  • Tabelle verwendet InnoDB (Schlüsselpuffer Verwendung ~ 98%)

PHP CPU Usage on CodeIgniter Query

Bitte lassen Sie mich wissen, was Sie denken, und wo soll ich oder vielleicht suchen, was genau soll ich suchen werden zum. Ich würde gerne sagen, dass dies ein CodeIgniter-Fehler ist, aber nach dem Protokoll, eine zweite Meinung ist erforderlich, bevor ich es tue.

Vielen Dank im Voraus

+0

Verwenden Sie '$ this-> output-> enable_profiler (true)'? – Dan

+0

Nein, bin ich nicht. Ich habe den Code genau so bereitgestellt, wie er in der Anwendung verwendet wird. Geben Sie bei Bedarf bitte an, warum und warum eine Abfrage ohne den Profiler solche Probleme verursacht. Danke –

+1

Können Sie nur die Abfrage verwenden 'SELECT ID, Inhalt, erstellt, gesehen von Benachrichtigungen LIMIT 10' und sehen, ob Sie ein Problem haben? Wenn nicht, bedeutet das, dass die Filterung angeordnet sein könnte. Versuchen Sie 'SELECT ID, Inhalt, erstellt, gesehen von Benachrichtigungen ORDER BY erstellt DESC LIMIT 10'. Wenn das gut aussieht, ist die Bestellung gut. Filterung könnte ein Problem sein. Versuchen Sie 'SELECT ID, Inhalt, erstellt, gesehen von Benachrichtigungen WHERE receiver_id = 1 ORDER BY erstellt DESC LIMIT 10'. Wenn das in Ordnung ist, versuchen Sie '$ UserID = sprintf ("% d ", $ UserID);' vor '$ sql ...' um Ihre UserID in einen int zu konvertieren. – zedfoxus

Antwort

0

Antwort

Es scheint, das Problem überhaupt nicht auf der MySQL-Seite ist, und der Beweis ist, dass ich jede Menge von Zeilen abfragen kann ich in nur Millisekunden kann.

Nachdem der function LoadNotifications($UserID) die Ergebnisse zurück, und während CodeIgniter tatsächlich Rendering wurde die $results Array zurückkehrte, hatte ich eine Javascript-Zeile wie folgt aus:

foreach($results as $notification) 
{ 
    echo $notification["content"] . "<br />"; 
    echo "<script> some JS code </script>"; 
} 

Das Problem wird durch meine verwendet Inline Javascript Verschleierungs Bibliothek verursacht wurde CI_Minifier die verursachte, dass 100 Verschleierungs-Instanzen gleichzeitig gestartet wurden, um diese 100 <script> Zeilen, die ich innerhalb der Schleife hatte, zu verschleiern.

Bottom-line:

Wenn Sie Inline-PHP DOM-Parsing jeglicher Art verwendet werden, dass zum Beispiel der Code verschleiern kann oder an Drittanbieter-Software übergeben, stellen Sie sicher, dass Sie nicht enthalten das in einem Look, wenn Ergebnisse oder Rendercode zurückgegeben werden.

Der richtige Ansatz wäre die Erzeugung einer Ausgabe von welchem ​​Array Sie haben, verlassen Sie diese Schleife, dann Pipe die endgültige Ausgabe für die Verschleierung oder was auch immer Sie in einer einzigen Instanz tun.

Vielen Dank @zedfoxus und @Dan für Ihre Versuche, mir zu helfen.

0

Für die erste Abfrage benötigen Sie einen Index für created. Sie müssen diese Spalte wahrscheinlich in einen numerischen Datentyp umwandeln, nicht VARCHAR. Für die zweite Abfrage benötigen Sie einen anderen Index, den Composite INDEX(receiver_id, created). Ihre aktuelle INDEX(receiver_id) ist nicht so gut. Da es ein Präfix von dem ist, das ich empfehle, empfehle ich dir, dein zu entfernen.

+0

Während ich Ihre Eingaben und Kommentare zur Verbesserung der Leistung der Datenbank schätze, möchte ich erwähnen, dass dies absolut nicht mit meiner Frage zusammenhängt und auch das angeführte Problem nicht löst. Danke –

+0

"Timeout" und "essen alle CPU" Smack "Leistung". 'result *' wartet darauf, dass die Datenbank die gesamte Ergebnismenge abruft. –

+0

nicht wirklich, bitte sehen Sie meine Antwort unten. Ich war "in-line" obfuscating JS renturned mit dem Ergebnis, das Hunderte von Instanzen der Inline-Verschleierung Modul gefeuert. Das '$ result' wird in 0,01 Sekunden zurückgegeben, egal wie marge, es war kein DB-Problem, danke. –

Verwandte Themen