2012-03-23 14 views
1

Entschuldigung, dies ist das erste Mal, dass ich dieses Forum nutze. Anscheinend können Leute meinen Beitrag bearbeiten, der, obwohl er hilfreich ist, einige Informationen herausgenommen hat. Ich werde versuchen, es verständlicher zu machen.Wie verbessert man die Geschwindigkeit dieser SQL-Update-Abfrage?

Ich verwende SQL Compact 3.5 als lokale Datenbank. Das Programm ist in VB.NET geschrieben.

Das Problem ist mit der Abfrage einer meiner Tabellen, die zu lange dauert.

Der Spieler Tabelle hat, unter anderem, id, skill, school, weight, starter.

  • id ist die ID des Spielers
  • skill ist die Spielstärke des Spielers
  • school auf die ID der Schule Tabelle ein Fremdschlüssel Zeige ist
  • weight ist einer von 14 verschiedenen Nummern

Was ich versuche zu tun, ist die starter value = 'true' für den Spieler mit der höchsten Fertigkeit bei einem bestimmten Gewicht für eine bestimmte Schule. Wenn also 100 Spieler an einer Schule sind, gibt es 14 Starter, einen für jedes Gewicht.

Der Spielertisch hat 170.000 Spieler, jeder hat 1 von 14 verschiedenen Gewichten und jeder gehört zu 1 von 4500 Schulen.

Jemand kommentierte unten und zeigte diese Aussage, die auf dem richtigen Weg zu sein scheint. Ich bin ein Neuling und habe es noch nicht umgesetzt.

"UPDATE p " & 
    "SET starter = 'TRUE' " & 
    "FROM player p" & 
    "JOIN (" & 
    "SELECT DISTINCT school, weight, MAX(skill) AS MaxSkill " & 
    "FROM player " & 
    "GROUP BY school, weight" & 
    ") q ON q.school = p.school AND q.weight = p.weight AND q.MaxSkill = 
    p.skill" 
+0

Ist Gewicht ein Bereich oder eine Zahl? Dh soll nur 14 mit 14 oder auch mit zB 13-15 gewogen werden? –

+0

Einfache Antwort - mach es nicht eine Schule/Gewicht zu einer Zeit. – Bridge

+0

Zeigen Sie ein Beispiel von dem, was Sie als Ausgabe wollen, nicht wirklich klar von Ihrer Frage. – Sparky

Antwort

3

Statt eine Gruppe-für-Gruppe zu tun, Zeile-für-Zeile-Ansatz, dieses Update-Abfrage funktioniert das alles auf einmal:

Erstens ist es die höchste skill für jede sammelt school/weight Kombination .

Es schließt sich dann, dass in die player daß die Anpassung school/weight/skill Kombination hat, und setzt dann das player an den Starter.

UPDATE p 
SET starter = 'TRUE' 
FROM player p 
JOIN (
    SELECT school, weight, MAX(skill) AS MaxSkill 
    FROM player 
    GROUP BY school, weight 
) maxResults 
    ON maxResults.school = p.school 
    AND maxResults.weight = p.weight 
    AND maxResults.MaxSkill = p.skill 

jedoch im Falle eines Unentschiedens in Geschicklichkeit, alle Spieler mit dem höchsten Skill würde einen Starter eingestellt werden ...

1

Es gibt einige kleinere Verwirrung über die Verwendung von weight, wie ich Ich nehme an, Sie tun das nicht pro Einheit. Vielleicht möchten Sie Bereiche in eine andere Tabelle extrahieren und dann die IDs anstelle einer numerischen Gewichtung verwenden.

In jedem Fall ist hier eine Abfrage, die für alle RDBMS

UPDATE player a SET starter = TRUE 
WHERE NOT EXISTS (SELECT '1' 
        FROM player b 
        WHERE b.school = a.school 
        AND b.weight = a.weight 
        AND b.skill > a.skill) 

Die innere Abfrage null funktionieren sollte (also Einstellung starter true), wenn zurückkehren sollte:

  1. Es gibt keine anderen Spieler an Die Schule
  2. Es gibt keine Spieler an der gleichen Schule, in der gleichen Gewichtsklasse
  3. Es gibt keine Spieler w iit einem höheren Qualifikationsniveau, für die gleiche Schule und Gewichtsklasse
+0

+1 Für mehr Datenbank agnostic als meine Antwort. –

+0

Ich erhalte einen Fehler, wenn ich versuche, den Alias ​​innerhalb des Updates zu setzen. Wie mache ich das für SQL compact Server 3.5? Ich habe eine ähnliche Frage gefunden, aber ich war nicht in der Lage, das herauszufinden. http://stackoverflow.com/questions/4981481/how-to-write-update-sql-with-table-aliass-in-sql-server-2008 – Meowbits

+0

@Meowbits - Sie müssen das 'wie' entfernen, die anscheinend sind nicht agnostisch –

Verwandte Themen