0

Ich sehe diese Abfrage in New Relic als Tausende von Sekunden unter:Rails-generierte Abfrage dauert Tausende von Sekunden

SELECT "apps".* FROM "apps" WHERE "apps"."listing_id" = $1 ORDER BY "apps"."id" ASC LIMIT 1 

Es zerstört nur meine Leistung. Die Tabelle ist schlecht, da sie über 50 sehr dünn besetzte Spalten und etwa 50 Millionen Zeilen enthält.

listing_id ist indexiert. Dies ist eine PostgreSQL Datenbank und ich mache buchstäblich nichts anderes, was es erlaubt, auto vacuum Ed jeden Tag zu sein.

Aber ich weiß nicht, wo ich suchen soll, um die Abfrage schneller zu machen. Diese Abfrage wird von generiert. Es sieht so aus, als ob es wahrscheinlich nur verwendet wird, um die Attribute der Tabelle zu erhalten, die mein Modell sichern. Gibt es eine Möglichkeit, das zu cachen, damit ich die Abfrage nicht ausführen muss?

Oder gibt es noch etwas, was ich tun kann, um dies "performant" zu machen? Bitte beachten Sie, dass ich dieselbe Frage auf der SE DBA-Site etwas anders gestellt habe. Daher muss diese Frage nicht neu klassifiziert werden. Ich konzentriere mich hier darauf, herauszufinden, warum AR diese Abfrage erzeugt, und kann ich etwas tun, um es zu ändern oder es leistungsfähiger gegen solch eine Schwachstelle einer Tabelle zu machen.

+0

Was sagt Postgres über die Abfrage? Vielleicht kann ein Index zu "listing_id" helfen. – xlembouras

Antwort

0

Das Problem ist, Sie suchen nach der kleinsten apps.id, und das ist nicht Teil des Index. Also müssen alle übereinstimmenden Zeilen gelesen werden, um die ID zu erhalten, und dann sortiert werden. Ich vermute, dass das Zeit braucht.

Ein Verbundindex auf [listing_id, id] sollte das Problem lösen.

+0

Die problematische Aussage lautet: '' 'apps.first.standard'''. Zur Laufzeit enthält '' 'apps''' noch nicht die Daten. Würde diese Aussage das "Limit 1" auslösen? – AKWF

+0

'.first' bewirkt' order by ID ASC limit 1'. Das ist ziemlich schnell, wenn man annimmt, dass Ihre Tabelle mit ID indiziert ist. Ich gehe davon aus, dass "Standard" ein Bereich ist, der den '.listing_id' Teil einführt. Zu diesem Zeitpunkt kann der ID-Index nicht verwendet werden. – z5h

+0

@AKWF Ich habe meine vorgeschlagene Lösung hinzugefügt. – z5h

1
SELECT "apps".* FROM "apps" 
WHERE "apps"."listing_id" = $1 ORDER BY "apps"."id" ASC LIMIT 1 

in Schienen können durch eine Reihe von Aussagen generiert werden.

können Sie haben

  • App.where(listing_id: X).first
  • a_listing.apps.first

, so dass Sie für diese beiden aussehen könnte.

Verwandte Themen