Welches ist die effizienteste SELECT-Methode und warum?

8

Stellen Sie sich eine Seite vor, auf der die Nutzer ihre Lieblingsfarbe wählen (+1) oder weniger (-1) und ich zwei Tabellen habe:

Man listet alle Farben auf, für die man stimmen kann, und die zweite Tabelle zeichnet jede einzelne abgegebene Stimme auf, welche Farbe sie hatte und ob +1 oder -1 war.

Wenn es darum geht, die Gesamtabstimmung für eine bestimmte Farbe abzurufen, wäre es effizienter, eine Gesamtpunktzahl in der Farbtabelle einzubeziehen, und wenn eine Person dort abstimmt, gibt es eine insert-Anweisung und eine update-Anweisung:

%Vor%

Oder wäre es effizienter, nur eine einzige INSERT-Anweisung zu haben, wenn eine Abstimmung vorgenommen wird, und dann die Punktezahl abzurufen?

%Vor%

Ich denke, wenn es eine sehr kleine Anzahl von Stimmen gibt, dann ist Option # 2 am besten, aber wird Option # 1 besser, wenn die Stimmen-Tabelle sehr groß ist?

Gibt es ein Tool, mit dem ich bei bestimmten SQL-Abfragen je nach Tabellengröße usw. eine Rangliste erstellen kann?

    
Alwayslearning 08.03.2013, 10:02
quelle

4 Antworten

4

Persönlich denke ich, wenn Sie eine Gesamtpunktzahl anzeigen möchten (und ich stelle mir vor, dass Sie die Punktzahl häufig anzeigen möchten), dann, wenn die Anzahl der Zeilen in der Wahltabelle zunimmt, werden Sie feststellen, dass die Summe SUM query dauert länger und länger und skaliert nicht sehr gut.

Wenn Sie außerdem Abfragen implementieren möchten, die nur Farben mit einer Punktzahl von 100 oder mehr anzeigen, führt das Aggregieren zu einfacheren und schnelleren Abfragen.

Ein weiterer Vorteil der Verwendung der Score-Spalte besteht darin, dass Sie die votes -Tabelle löschen möchten (zB wenn sie zu groß wird), wenn Sie zu einem späteren Zeitpunkt die Farbwerte verlieren möchten.

Ich glaube nicht, dass dies eine vorschnelle Optimierung ist. Ich denke, dass dies ein System mit Skalierung ist. Also würde ich einige Beispieldatensätze mit einer realistischen Anzahl von Stimmen, Farben und Abfragen pro Minute erstellen. Ich erwarte und führe einige Leistungstests durch, um zu bewerten, welcher der bessere Ansatz ist, denn es ist einfacher (lies billiger), den richtigen Ansatz zu wählen, anstatt ihn zu reparieren, wenn die Dinge schief gehen.

    
beny23 08.03.2013, 10:22
quelle
1

Der Leistungsunterschied zwischen den beiden Abfragen ist trivial. Sie sollten die Struktur basierend auf den Informationen bestimmen, die Sie behalten möchten.

Wenn Sie nur eine Gesamtpunktzahl benötigen, verwenden Sie

%Vor%

Das wird sehr schnell, weil die Tabelle colours nur ein paar Zeilen hat.

Andererseits könnte es einen Grund geben, die Stimme jedes Nutzers zu speichern (z. B. um sicherzustellen, dass sie nicht zweimal wählen). In diesem Fall fügen Sie für jede Abstimmung eine Zeile ein.

%Vor%

Aber erstellen Sie keine Struktur unnötiger Zeilen, nur weil Sie denken, dass sie schneller ist.

    
user1919238 08.03.2013 10:10
quelle
0

Optimieren Sie vorzeitig oder ist das ein echtes Problem?

Der erste Ansatz ist möglicherweise schneller, aber Sie ändern Ihr Domänenmodell aus Gründen der Optimierung. Es ist in Ordnung, solange Sie wissen, was Sie tun und welche Nachteile es Ihnen bringt (wahrscheinlich Notwendigkeit, zwei Tabellen an allen Stellen zu aktualisieren, die mit Stimmen arbeiten, was zum Beispiel zu Fehlsynchronisierung führt)

Aber Sie könnten andere Optionen in Erwägung ziehen. Wenn beispielsweise die Anzahl der Farben nicht so groß ist, könnten Sie ein Caching für ihre Bewertungen erstellen. Das wird das einfache Modell behalten, einfache Rating-Mechanik und bieten Geschwindigkeit, die Sie brauchen, abzüglich etwas Speicher;)

    
durilka 08.03.2013 10:15
quelle
0

Der Schlüssel zu dieser Art der Optimierung ist was Sie optimieren möchten. Wenn Sie die Summe speichern, dauert das Einfügen / Löschen / Aktualisieren länger. Die Berechnung der Summe beeinflusst die Leistung von Abfragen für die Daten.

Wenn Sie Daten löschen oder aktualisieren, sehen Sie schnell die Torheit, die Summe vorzurechnen. Jede solche Änderung an den Daten erfordert Änderungen an mehreren Datensätzen, wenn Sie der Meinung sind, dass Sie nur einen ändern.

Ihre Struktur scheint jedoch nur Einsätze zu haben - eine gute Designwahl übrigens, weil Sie jede Veränderung sehen. In diesem Fall lautet die Frage, ob Sie den Overhead für jede Einfügung verwenden möchten oder ob Sie den Overhead auf der Seite "Berichterstellung" verwenden möchten. Die Frage ist in bestimmten Fällen einfach.

Wenn Sie 1000 Stimmen für jedes Mal haben, wenn Sie die Summe betrachten, berechnen Sie die Summe im laufenden Betrieb. Wenn Sie 1000 Summen für jede Stimme haben, dann sieht das Speichern der Summe wie der effizientere Ansatz aus.

Meine Vermutung ist, dass die Arbeitsbelastung irgendwo zwischen den Extremen liegt. Meine natürliche Voreingenommenheit besteht darin, die Daten so zu speichern, wie sie erzeugt werden, und dann zusätzliche Tabellen für Zusammenfassungen und Berichte zu haben. Ich würde einen der folgenden zwei Ansätze empfehlen:

(1) Behalten Sie nur die Transaktionsdaten und berechnen Sie die Summen im laufenden Betrieb. Ordne die Indizes auf der Tabelle an, um die Summen so effizient wie möglich zu machen.

(2) Behalten Sie nur die Transaktionen in einer Tabelle und berechnen Sie die Summen in einer anderen Tabelle (entweder mit einem Trigger oder einer gespeicherten Prozedur). Dadurch erhalten Sie die aktuellen Werte, die für die meisten Zwecke benötigt werden. Die Einfügungen sollten effizienter sein als das Speichern der Summe in jedem Datensatz (weil die Tabelle auf Benutzerebene kleiner ist als die Tabelle auf der Vote-Ebene).

Ihr Vorschlag, die Summe in den Stimmaufzeichnungen zu berechnen, wäre normalerweise keine Option, die ich in Betracht ziehen würde. Es wäre wünschenswert, wenn Sie die Geschichte der inkrementellen Stimmen benötigen. Aber wenn Sie sich die Historie ansehen, dann wäre es auch machbar, die sum Berechnung durchzuführen oder die Summe in der Anwendungsschicht zu berechnen.

    
Gordon Linoff 08.03.2013 12:07
quelle

Tags und Links