Einzelnen Beitrag anzeigen

alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#5

Re: Und gleich nochmal MAX(), diesmal mit MSSQL.

  Alt 16. Jan 2006, 20:44
nochwas:
select @Nummer = max (Nummer) from Nummern where Datum is null So würde ich das machen.
Nun zu Deiner Frage:
select top 1 Nummer from Nummern where Datum is null order by nummer desc scheint etwas (aber wirklich nur etwas) besser zu sein, als
select max (Nummer) from Nummern where Datum is null aber nur unter der Voraussetzung, das Nummern und Datum indiziert ist. Ohne das näher zu analysieren würde ich annehmen, das der clustered Index auf dem 'Datum' liegen muss, damit die beiden Versionen identisch sind.

Ansonsten ist Variante 1 (also MAX) eindeutig besser, ohne Index ca. 10x schneller. Mit einfachen Indizes ca 3x. Ich denke, das liegt am Sortieren. Ich hab das rudimentär mit einer 100.000 Tabelle getestet, da tut das Sortieren natürlich weh. ORDER BY wird nur bei clustered indexen ignoriert, denn da liegen die Daten schon richtig sortiert vor.

Unabhängig davon ist es blasphemisch, die nächste Rechnungsnummer so zu erzeugen (finde ich). Denn der Server wird überflüssigerweise mit Arbeit zugeballert (außer, die Indexe stimmen). Stell Dir einfach vor, es wären 100.000.000 Rechnungen (na ja, wer hat die schon, aber egal).

Ich arbeite gerade am gleichen Problem und verwende einen Zähler. Ich habe eine Tabelle mit Rechnungen, die nun fakturiert werden sollen. Ich erzeuge eine temporäre Tabelle über dynamisches SQL, und zwar mit zwei Spalten ('IDRechnung' und 'RechnungsNr'). Die RechnungsNr wird als Identity deklariert, der Seed wird auf die nächste freie Rechnungsnummer gesetzt. Das geht mit plain SQL nicht, also erzeuge ich mir das folgende Statement als String und führe es einfach mit EXEC aus:
SQL-Code:
CREATE TABLE #Foo (
  IDRechnung int, 'ü
RechnungsNr int identity (12345,1)
)
Die Tabelle erzeugt also automatisch neue Rechnungsnummern, sobald die Tabelle gefüllt wird, und zwar so:
SQL-Code:
insert into #Foo (IDRechnung)
  select IDRechnung from Rechnungen where Status='Offen'
Damit habe ich optimal schnell und garantiert fortlaufend alle Rechnungsnummern erzeugt. Danach kopiere ich die Rechungsnummern in die Rechnungstabelle zurück:
SQL-Code:
Update Rechnungen
   set RechnungsNr = #Foo.RechnungsNr
  From #Foo
 Where Rechungen.RechungsNr = #Foo.RechungsNr
Zum Schluss nur noch die neue maximal Rechnungsnummer in meine Zählertabelle eintragen und fertig.
Update Counters Set Counter = (select max (RechnungsNr)+1 from #Foo) where cntID = 2
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat