Es ist den ganzen Tag, dass ich versuche, die Ursache eines seltsamen Fehlers herauszufinden.Rails: SQL-Abfrage lässt Produktionsserver für immer hängen
Ich habe diese Zeile Code in einem Modell (die durch eine Controller-Aktion aufgerufen wird):
# it always works
self.deliveries.create(subscriptions.pluck('DISTINCT endpoint').collect {|e| {endpoint: e}})
Alles funktioniert wie erwartet (auf meinem lokalen Rechner, auf dem Produktionsserver und sogar mit Tausenden von Lieferungen).
# it hangs forever on the production server if you have many deliveries
inserts = subscriptions.pluck('DISTINCT endpoint').collect do |e|
"(#{self.id}, #{ActiveRecord::Base::sanitize(e)})"
end
ActiveRecord::Base.connection.execute("INSERT INTO deliveries (notification_id, endpoint) VALUES #{inserts.join(', ')}")
Das auf meinem lokalen Rechner wie erwartet funktioniert auch mit Tausenden von Lieferungen:
Um Steigerung der Leistung Ich habe die obige Zeile mit roher SQL ersetzt. Jedoch auf meinem Produktionsserver (2 GB RAM/2 Kerne) diese zweite Version funktioniert nur, wenn ich ein paar Datensätze einfügen, sonst mit 2000 Lieferungen oder so hängt die Anfrage für immer.
Um genauer zu sein:
- der Browser keine Antwort und die HTTP-Anforderung in der Datenbank folgenden hängt gespeichert bekommt immer
- die Lieferungen
- die Linien die
execute
werden nie ausgeführt
Wenn ich eine dritte Version von Code verwende und ich das rohe SQL durch die Verwendung von activerecord-import Edelstein ersetze, bekomme ich genau den gleichen Fehler.
Was kann diesen Fehler verursachen?
Ich frage mich sogar, ob es die lange Ausgabe Nachricht generiert werden kann (die große SQL-Abfrage), die die Anwendung abstürzt (ich benutze logz.io).
Warum sind Sie beteiligt Rails in das alles zu? Ein einfaches 'Insert in ... Select ...' Bit von SQL wäre ein besserer Startpunkt, oder? –