4 Stimmen

Effiziente Suche nach eindeutigen Werten in einer Datenbanktabelle

Ich habe eine Datenbanktabelle mit einer sehr großen Anzahl von Zeilen. Diese Tabelle stellt Meldungen dar, die von einem System protokolliert werden. Jede Meldung hat einen Meldungstyp und dieser wird in einem eigenen Feld in der Tabelle gespeichert. Ich schreibe eine Website zur Abfrage dieses Meldungsprotokolls. Wenn ich nach dem Meldungstyp suchen möchte, würde ich idealerweise ein Dropdown-Feld haben wollen, in dem die Meldungstypen aufgelistet sind, die in der Datenbank aufgetaucht sind. Die Nachrichtentypen können sich im Laufe der Zeit ändern, so dass ich die Typen nicht fest in die Auswahlliste einfügen kann. Ich muss eine Art von Lookup durchführen. Das Iterieren über den gesamten Tabelleninhalt, um eindeutige Meldungswerte zu finden, ist offensichtlich sehr dumm, aber da ich auf dem Gebiet der Datenbank dumm bin, frage ich hier nach einem besseren Weg. Vielleicht wäre eine separate Nachschlagetabelle, die von der Datenbank gelegentlich aktualisiert wird und nur die eindeutigen Nachrichtentypen auflistet, aus denen ich meine Auswahlliste auffüllen kann, eine bessere Idee.

Für Vorschläge wären wir sehr dankbar.

Die von mir verwendete Plattform ist ASP.NET MVC und SQL Server 2005

0voto

c. liau Punkte 21

Haben Sie eine indizierte Ansicht in Betracht gezogen? Die Ergebnismenge ist materialisiert und wird im Speicher gehalten, so dass der Overhead der Suche vom Rest der Aufgabe getrennt ist.

SQL Server kümmert sich um die automatische Aktualisierung der Ansicht, wenn es eine Datenänderung gibt, die seiner Meinung nach den Inhalt der Ansicht ändern würde, so dass er in dieser Hinsicht weniger flexibel ist als Oracle Materialized.

0voto

Adriaan Stander Punkte 155899

Der MessageType sollte ein Fremdschlüssel in der Haupttabelle zu einer Definitionstabelle sein, die die Codes und Beschreibungen der Nachrichtentypen enthält. Dies wird die Suchleistung erheblich steigern.

Etwas wie

DECLARE @MessageTypes TABLE(
        MessageTypeCode VARCHAR(10),
        MessageTypeDesciption VARCHAR(100)
)

DECLARE @Messages TABLE(
        MessageTypeCode VARCHAR(10),
        MessageValue VARCHAR(MAX),
        MessageLogDate DATETIME,
        AdditionalNotes VARCHAR(MAX)
)

Von diesem Entwurf aus sollte Ihr Lookup nur abfragen MessageTypes

0voto

Jay Punkte 26044

Wie bereits von anderen erwähnt, sollten Sie eine separate Tabelle mit den Nachrichtentypen erstellen. Wenn Sie der Nachrichtentabelle einen Datensatz hinzufügen, prüfen Sie, ob der Nachrichtentyp bereits in der Tabelle vorhanden ist. Wenn nicht, fügen Sie ihn hinzu. In beiden Fällen buchen Sie den Bezeichner aus der Nachrichtentyp-Tabelle in die Nachrichtentabelle. Damit sollten Sie normalisierte Daten erhalten. Ja, es kostet etwas mehr Zeit, wenn Sie einen Datensatz hinzufügen, aber es sollte beim Abruf effizienter sein.

Wenn es viel mehr Hinzufügungen als Lesungen gibt und wenn der "Nachrichtentyp" kurz ist, wäre ein völlig anderer Ansatz, die separate Nachrichtentyp-Tabelle zu erstellen, aber nicht darauf zu verweisen, wenn man Hinzufügungen vornimmt, und sie nur bei Bedarf zu aktualisieren.

Und zwar: (a) Aufnahme eines Zeitstempels in jeden Nachrichtendatensatz. (b) Führen Sie eine Liste der Nachrichtentypen, die bei der letzten Überprüfung gefunden wurden. (c) Suchen Sie bei jeder Überprüfung nach allen neuen Nachrichtentypen, die seit der letzten Überprüfung hinzugefügt wurden, wie in

create table temp_new_types as
    (select distinct message_type
    from message
    where timestamp>last_type_check
);

insert into message_type_list (message_type)
select message_type
from temp_new_types
where message_type not in (select message_type from message_type_list);

drop table temp_new_types;

Speichern Sie dann den Zeitstempel dieser Prüfung irgendwo, damit Sie ihn beim nächsten Mal wieder verwenden können.

0voto

Die Antwort ist die Verwendung von "DISTINCT" und jede beste Lösung ist für verschiedene Tabellengrößen unterschiedlich. Tausende von Zeilen, Millionen, Milliarden ? mehr ? Dies sind sehr unterschiedliche beste Lösungen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X