2009-04-09 16 views
1

Standard-EAV-Schema: Eine Spalte für Entity ID, eine für Attribute ID, eine für Value ID.Was ist der schnellste Weg zur Abfrage von einer historischen EAV-Datenbank

Historische EAV Schema: Fügen Sie eine zusätzliche Spalte (e) für Zeiten/Datumsbereiche

Zur Laufzeit werden bestimmte Zeilen ausgeschlossen werden. Es können 0, 1 oder viele Zeilen pro Entität pro Attribut zurückgegeben werden. Wir wollen nur den letzten Wert für jedes verbleibende Attribut.

Unsere aktuelle Lösung verwendet die SQL Server Rank() -Funktion, um jede Zeile mit einem Rang zu markieren, und dann in der Where-Klausel haben wir "und Rang = 1".

Die Leistung ist jedoch nicht zufriedenstellend. Während der Analyse stellen wir fest, dass das Zuweisen der Ränge ziemlich schnell ist, aber das Ausführen der where-Klausel gegen den Rang erfordert einen zweiten Scan der Daten und hält den gesamten Datensatz im RAM.

Was ist der schnellste Weg, um die verbleibenden Attributzeilen zu ranken und nur die neuesten zu liefern?

+0

Befolgen Sie diese Anweisungen, um weitere Informationen zu Ihrer langsamen Abfragefrage zu veröffentlichen: http://www.brentozar.com/archive/2009/03/getting-help-with-a-slow-query/ –

Antwort

1

Die allgemeine Idee wäre, die neueste + Taste zuerst zu extrahieren, dann wieder zu verbinden, um den Wert zu erhalten, der nicht Teil des Aggregats ist. Die Tatsache, dass es EAV ist, spielt keine Rolle.

SELECT 
    * 
FROM 
    table t 
    JOIN 
    (SELECT MAX(dt) AS mdt, eID, aID FROM table GROUP BY eID, aID) mt 
        ON t.eID = mt.eID AND t.aID = mt.aID AND t.dt = mt.mdt 
WHERE 
    ... 
1

Während ich gbn Antwort denken wahrscheinlich ausreichend ist, frage ich mich, ob die Verwendung einer OVER-Klausel eine MAX Datum pro id/Attribut zu schaffen, mit denen die SELECT in eine reduzieren WHERE-Klausel nicht schneller sein würde, als ein RANK? Keine Zeit, um die Leistung zu testen, aber hier ist die Abfrage:

select * 
from (
    select *, max(dt) over (partition by eID, aID) maxdt 
    from table 
) t 
where t.dt = t.maxdt and ... 

Viel Glück!