C#-Abfrage und Datenbank-Index, welcher Index ist besser?



  • Was ist besser (im speziellen Fall für MS SQL Server, aber ich verwende auch PostgreSQL - gibt es da, bzw. für andere Datenbanken Unterschiede für diesen Fall)?

    EDIT:
    Habe ich glaube Mist geschrieben 😞 Es gibt ja nur DateTime in Transact-SQL,
    insofern wird das nie eindeutig sein. Ich werde also Alternative 1 (abgewandelt) verwenden müssen.

    EDIT2:
    Ich kann ja programmtechnisch die DateTime-Spalte so abwandeln, dass als Zeit immer 00:00 Uhr bei DateTime steht, und eine extra Spalte mit der Zeit anlegen. Dann ist das Beispiel wieder aktuell.
    END EDIT2

    BTW: Gibt es wirklich keinen Datentyp in Transact-SQL, der nur das Datum speichert UND _NICHT_ Datum und Zeit zusammen?
    END EDIT

    create table share (
        id int identity (1,1) primary key
       ,usrpriority int -- The user may set a priority, which can be used in where clauses
       ,isin char(12) not null unique  -- official international securities identification number
       ,share character varying(50) -- full official name of the company
    );
    create unique index isinNdx on share (isin);
    create table price (
         id int primary key -- share.id -> price.id
        ,price smallmoney -- price of the share, German: Kurs
        ,date datetime
        ,spreadbid smallmoney -- German: Geld-Briefspanne (Geld)
        ,spreadask smallmoney -- German: Geld-Briefspanne (Brief)
        ,turnover money -- German: Umsatz
        ,exchange char(1) -- X: XETRA F: FRA (Frankfurt Parkett) German: Börsenplatz
    );
    -- Folgende Alternativen:
    -- Alternative 1:
    create index dateNdx on price (date);
    -- oder besser das, Alternative 2:
    create unique index idDateNdx on price (id, date);
    

    Die Datei share enthält alle AGs mit ihrer ISIN, dem Namen und dem
    Primary Key Identity(1,1) der auf auf den Primary Key in der price
    Tabelle (diese Tabelle soll die Kurse über mindestens 3 Jahre aller Aktien
    [ca. 3000] verwalten - wird also sehr groß) verweist.

    Beim Einfügen einer neuen Zeile in "price" soll zunächst ermittelt werden,
    ob für den heutigen Tag bereits ein Kurs ermittelt und in "price" gespeichert
    wurde. Falls ja, soll dieser Kurs aktualisiert (update ...) werden. Falls nicht
    soll ein neuer Datensatz mit den aktuellen Kursdaten angelegt werden.

    Der C#-Code für Alternative 1 wäre dann (habe es nicht getestet, ist
    also eher Pseudo-Code, sollte zum Verständnis ausreichen) wäre dann:

    cmd.Text="select * from price where date >="+IrgendWas.Today().ToString();
    rdr=cmd.ExecuteReader();
    if (rdr.Read()) {
        // update the row...
    }
    else {
        //insert the row...
    }
    

    Bei Alternative 2 würde ich folgenden Code verwenden:

    try {
        // insert the row...
    }
    catch (Exception excpt) {
        // update the row...
    }
    

    Meine Frage, da fehlt mir datenbanktechnisch die Erfahrung:

    **********************************************************************************

    Welche Alternative ist die bessere (Performancemäßig, Speicherbedarfsmäßig, ...)?

    **********************************************************************************

    Es wird in jedem Fall auch noch folgende SQL-Abfrage benötigt:

    select * from price where (id = xyz and date > IrgendEinDatum)

    Ich hoffe, es kommt mit diesem Pseudocode rüber, was ich machen will: Es soll
    für jeden Tag nur ein Kurs in der "price"-Tabelle sein, aber man soll die Kurse mehrmals
    täglich aus dem Internet abrufen können und in der "price"-Tabelle eintragen, bzw.
    falls schon drin, aktualisieren können.

    Vielleicht sollte ich natürlich auch ganz anders vorgehen (so viel Erfahrung habe
    ich mit RDBMSen leider noch nicht)...



  • Für sowas nimmst du bei T-SQL am besten MERGE.



  • hustbaer schrieb:

    Für sowas nimmst du bei T-SQL am besten MERGE.

    Was ist das? Sorry habe nur Visual Studio 2005 Professional. MERGE kann ich in meiner Transact-SQL-Hilfe (außer "Partition.Merge.Method(Microsoft.AnalysisServices)" - das hast Du vermutlich nicht gemeint[?]) nicht finden.



  • http://lmgtfy.com/?q=T-SQL+MERGE

    Und frag bitte nicht wie du das dann genau schreiben musst o.ä., das kannst du alles auf der MSDN Seite nachlesen.



  • Danke! Aber wie ich befürchtet hatte, wird von der 2005'er-Version noch nicht unterstützt. Evtl. installiere ich mal die aktuelle Version und schaue, ob die zusammen mit Visual Studio 2005 Professional funktioniert.



  • Funktioniert wunderbar zusammen.

    BTW: von "deinen" zwei Möglichkeiten ist mMn. die if (rdr.Read()) besser. Was schneller ist kann man schwer sagen, müsstest du probieren.


Anmelden zum Antworten