Rails Abfrage langsam aber schnell in pgAdmin

8

Ich versuche herauszufinden, warum eine der Suchanfragen in meiner Rails-App ganz erheblich schlechter abschneidet. Ich benutze Postgres 9.3 und Schienen 4.0.3 mit jRuby 1.7.10, also möglicherweise ein Problem mit dem JDBC Treiber?

Aber im Grunde ist es eine sehr einfache Abfrage:

%Vor%

Die Tabelle enthält 851 rows, also handelt es sich kaum um ein riesiges Dataset, daher erwarte ich eine schnelle Abfrage. Wenn ich diese Abfrage in pgAdmin 3 ausführe, bekomme ich genau das, was ich erwarte: alle Zeilen, die irgendwo zwischen 15 und 35ms zurückgegeben werden. Schön und schnell!

Von den Schienen jedoch ist es eine andere Geschichte. Wenn ich die Abfrage in einer Rails-Konsole durchführe, bin ich am schnellsten in der Lage, 189ms zu erreichen, während es in der Regel um die 200ms -Marke geht. Diese Abfrage wird ausgeführt, indem Table.all

aufgerufen wird

Mein erster Gedanke war einfach, dass ActiveRecord Overhead bei der Instanziierung von 851 Objekten hinzufügt, so dass es offensichtlich langsamer wird. Um das zu testen, habe ich

ausgeführt %Vor%

Es gab eine leichte Beschleunigung, aber auch hier gingen fast alle Abfragen um 150ms herum, immer noch weit von der pgAdmin-Marke entfernt. Als letzten Versuch versuchte ich

%Vor%

Aber das hat die Leistung überhaupt nicht verbessert.

Ich bin wirklich ratlos, warum das so viel langsamer ist, da ich eine 10fache Leistungsminderung zwischen pgAdmin und Rails sehe. Nachdem ich nur das rohe SQL in Rails ausgeführt habe, weiß ich, dass es nicht ActiveRecord ist, das die Dinge verlangsamt, also bin ich jetzt wirklich verwirrt darüber, was ist.

Weiß jemand, warum das so viel langsamer ist, als es sein sollte?

AKTUALISIEREN

Ich habe etwas mehr gegraben und es scheint in der Art und Weise zu sein, in der Schienen Datumsfelder bearbeiten. Wenn ich manuell alle Spalten in der Tabelle auswähle, ist es genauso langsam, aber wenn ich sie alle außer updated_at und created_at auswähle, läuft die Abfrage in ungefähr 2-4ms, was perfekt ist!

Mein einziges Problem ist jetzt, wie ich das umgehen kann. Gibt es eine Möglichkeit, das Leistungsproblem der Schienen mit Daten zu beheben oder Schienen nicht als Daten zu analysieren und sie als Strings oder ähnliches zu behalten?

UPDATE 2

Nachdem ich also etwas mehr gegraben habe und @stonehz mich auf den Fehler dieses Posts hingewiesen habe, habe ich ein Upgrade auf Jruby 1.7.12 und rails 4.1.0 durchgeführt und eine beachtliche Beschleunigung bemerkt. Es ist nicht viel näher an der Leistung von pgAdmin, aber ich denke, ohne die Datumsspalten komplett zu entfernen, werde ich nichts Besseres bekommen. Unten ist der Benchmark, den ich jetzt bekomme

%Vor%

Dieser Benchmark fragt 851 Zeilen ab. Der erste Test ist eine einfache SELECT * -Anweisung. Der zweite Test wählt nur die Datumsfelder aus und der letzte Test wählt alle Felder außer für die Datumsfelder aus. Jede Abfrage wird 100 Mal ausgeführt, um das Endergebnis zu erhalten.

Wie Sie sehen, dauert die Anweisung select * jetzt nur ~ 4 Sekunden, um 100 Mal ausgeführt zu werden. Daher nimmt jede Abfrage nur 40ms , was viel näher an der pgAdmin-Zeit von ~ 30ms liegt. Viel besser!

    
PaReeOhNos 28.02.2014, 16:36
quelle

2 Antworten

1

Sie haben das Problem angesprochen und paar Tickets um den gefundenen Fehler herum geöffnet:

Ссылка

Ссылка

Die Verwendung von Jruby 1.7.12 verbessert die Leistung um das 5-fache (wie ihre Benchmarks andeuten)

    
stonehz 07.05.2014, 10:06
quelle
0
  

Ich bin wirklich ratlos, warum das so viel langsamer ist, da ich eine 10fache Leistungsminderung zwischen pgAdmin und Rails sehe. Nachdem ich nur das rohe SQL in Rails ausgeführt habe, weiß ich, dass es nicht ActiveRecord ist, das die Dinge verlangsamt, also bin ich jetzt wirklich verwirrt darüber, was ist.

Es ist nicht ActiveRecord so viel wie Ihre Abfrage.

Wenn Sie diese Abfrage in pg admin ausführen, wird tatsächlich nicht ausgeführt, soweit mir bekannt ist. PgAdmin macht einige Vermutungen über Ihre Verwendung, nämlich dass Sie am Ende mit einem riesigen Set enden werden. Im Interesse der Leistung ist es interessanter, einen Cursor zu verwenden, um es Ihnen zu ermöglichen, durch den riesigen Satz zu navigieren, indem Sie die Reihen nach Bedarf und nicht alle gleichzeitig abrufen. Ich nehme an, dass genau das passiert.

Wenn Sie dieselbe Abfrage in Ihrer App ausführen, sind Sie dagegen dafür verantwortlich. Oder, zu diesem Zweck, nicht diese Art von Abfrage zu Beginn mit. Die Auswahl aller Zeilen aus einer Datenbanktabelle ist normalerweise ein Zeichen dafür, dass im Design Ihrer App etwas nicht stimmt.

    
Denis de Bernardy 06.05.2014 07:17
quelle