2016-07-11 23 views
0

Ich muss den zuletzt erstellten Datensatz in einem Tabelle/Rails-Modell finden, und ich möchte es auf eine effiziente Art und Weise tun. Mein Primärschlüssel ist eine UUID, daher funktioniert die Methode Rails Samples.last nicht. Googelnd hierfür verwenden die Top-Rails-Antworten eine sort ordered in descending order with a limit of 1. Natürlich ist das nicht der einzige Weg, dies zu tun, und als ich vor ein paar Jahren Datenbanken-Kurse besuchte, machten wir so etwas oft mit einer linken äußeren Verbindung.Den letzten Datensatz finden: linker äußerer Join vs. absteigend sortieren

Ich versuchte beide Methoden in SQLServer, aber ich bin nicht so vertraut mit erklären und kann nicht sagen, welche besser ist. Ich habe versucht:

SELECT TOP 1 * FROM samples ORDER BY created_at DESC; 

Diese Erläuterung zeigte eine Sortierung mit einem Clustered-Index-Scan.

SELECT * FROM samples s1 
LEFT OUTER JOIN samples s2 ON s1.created_at < s2.created_at 
WHERE s2.user_id IS NULL; 

Die Erklärung für diese zeigt einen Filter mit einer verschachtelten Schleife mit zwei Clustered-Index-Scans.

Welche davon ist besser, oder sind sie vergleichbar? Oder gibt es eine andere Methode, die ich verwenden sollte? Die Sortierversion scheint mir klarer zu sein, deshalb möchte ich das auch tun (andere Entwickler in meinem Team wissen noch weniger über SQL und Datenbanken als ich), aber dies wird in großen Tabellen verwendet, so dass es effizient sein muss.

Auch wenn es wichtig ist, habe ich SQLServer dafür verwendet, aber ich habe auch MySQL-Datenbanken, so hoffe ich auf eine Datenbank-agnostische Antwort, wenn möglich.

+0

Nun TOP ist nicht Agnostiker – Strawberry

+0

Ich bin mir dessen bewusst, dass. In MySQL würde es natürlich mit Limit umgeschrieben werden. – Maltiriel

+0

Das ist für mich nicht offensichtlich ;-) – Strawberry

Antwort

1

Unter der Annahme, dass Ihre id Spalte einen Index und ein Primärschlüssel ist, könnte man davon ausgehen, dass der neueste Datensatz derjenige mit der höchsten ID-Nummer sein würde?

Die Abfrage wäre:

SELECT * FROM samples ORDER BY id DESC LIMIT 1; 

Oder Sie Sample.last verwenden können, was es für Sie tun würde.

Edit:

Da Ihr id ist ein uuid, ich würde empfehlen, einen Index der created_at Spalte hinzufügen Voll Table Scans zu vermeiden. Dann das Leben einfacher zu machen, können Sie die folgenden Bereiche zu Ihrem Modell hinzufügen:

scope :first, -> { order("created_at").first } 
scope :last, -> { order("created_at DESC").first } 

hoffe, das hilft!

+1

http://stackoverflow.com/questions/9780169/active-record-model-find-last Dies setzt eine ganze Zahl für einen Primärschlüssel voraus. Meine ist eine UUID. Ich werde die Frage bearbeiten, um diese Tatsache widerzuspiegeln. – Maltiriel

+0

@Maltiriel Ich aktualisierte die Antwort. –

+0

Die Frage ist nicht "Wie kann ich das in Rails machen".Ich weiß schon, wie es geht. Die Frage ist "Was ist der effizienteste Weg". Die Standardmethode von Rails führt nicht unbedingt zu den effizientesten Datenbankabfragen. – Maltiriel

0

Da Sie Ruby on Rails verwenden, haben Sie versucht, Sample.last zu verwenden?

Sie mehr hier lesen: (?) Finder Methods: Last

+0

http://stackoverflow.com/questions/9780169/active-record-model-find-last Mein Primärschlüssel ist eine UUID, also wird dies nicht funktionieren. – Maltiriel

0

Ich glaube, Sie tun können:

Sample.order(created_at: :desc).first 
Verwandte Themen