2010-09-01 11 views
9

Ich habe SQL Server 2005 Standard Service Pack 2 9.00.4053.00 (Intel X86)SQL Server: fasziniert von GETDATE()

Tabelle hat fast 30 Millionen Zeilen ..

Wenn ich

SELECT GETDATE(), * FROM 
<table> 

Identische Datum und Uhrzeit Wert einschließlich Millisekunden Teil zurückgegeben .. obwohl Abfrage ...

abzuschließen mehr als 3 Minuten in Anspruch nahm Ich habe bereits

http://sqlblog.com/blogs/andrew_kelly/archive/2008/02/27/when-getdate-is-not-a-constant.aspx

http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/66507b8b-4a74-44c1-9637-3ab5f75db6a0

Einer der Link gepostet I (markiert Antwort) deuten darauf hin, dass vor SQL 2005 GETDATE war determinis obwohl SQL 2000 BOL besagt GETDATE nondeterministic ist

Wenn ich ein Update mit Millionen von Zeilen mache

UPDATE tableName 
SET dateColumn = GETDATE() 

Ich weiß, dass Sie wirklich

DECLARE @DT datetime 
SET @DT = GETDATE() 
UPDATE table 
SET datecol [email protected] 

Ich bin wirklich verwirrt

tun wollen Was erwartetes Verhalten würde?

  1. Bei select-Anweisung ich früher
  2. Verhalten der Update-Anweisung geschrieben

Betrachtet man auf einem Tisch ein datecolun ist updateing mit 100 Millionen Zeilen Would datecolumn identisch Datum hat und Zeit in Millisekunden ....?

Antwort

3

Nach der Antwort von Martin Smith, Der Determinismus, auf den Bezug genommen wurde, war eine Änderung im UDF-Verhalten. In SQL Server 2000 konnten Sie GETDATE in einem UDF nicht verwenden. Sie können in SQL Server 2005. See this link too

Wie Martin Smith sagte, werden einige Funktionen pro Spalte pro Abfrage ausgewertet. Nicht pro Reihe. GETDATE ist eins, RAND ist ein anderes.

Wenn Sie Zeile für Zeile Auswertung von GETDATE benötigen, dann wickeln Sie es in udf.

Edit:

NEWID ist statistisch eindeutig. Es muss Zeile für Zeile ausgewertet werden, damit Sie nicht den gleichen Wert in einer anderen Zeile haben. Daher der CHECKSUM(NEWID()) Trick, um Zeile für Zeile Zufallszahlen zu generieren ...

+0

Danke, aber warum nicht NEWID verhält sich anders? zufällig dann ORDER BY NEWID() so newid() anders ... SELECT top 4 newid(), newid() von sys.objects – cshah

+0

jetzt verstehe ich, als ob Sie Zeilen zurückgeben möchten – cshah

+0

Was würde Update gleich verhalten? dh. UPDATE tableName SET dateColumn = GETDATE() OK es wird gleich .. dumm :-( – cshah

10

war nie deterministisch. Deterministisch bedeutet, dass es immer dasselbe Ergebnis zurückgibt, wenn dieselben Parameter übergeben werden.

In Verbindung mit rand() Es wird einmal pro Spalte ausgewertet, aber einmal ausgewertet bleibt für alle Zeilen gleich.

Es ist leichter, dieses Verhalten zu sehen, mit rand() als getdate()

select top 4 rand(), rand() 
from sys.objects 

Retour
---------------------- ---------------------- 
0.0566172633850772  0.431111195699363 
0.0566172633850772  0.431111195699363 
0.0566172633850772  0.431111195699363 
0.0566172633850772  0.431111195699363 

Wenn Sie versuchen, die folgenden

select top 10 getdate(), getdate() 
from sys.objects 

und Blick auf die ComputeScalar Benutzereigenschaften in Den tatsächlichen Ausführungsplan sehen Sie t GetDate() wird zweimal ausgewertet.

NB: Es ist möglich, dass dieses Verhalten der Auswertung pro Spalte und nicht pro Abfrage nach SQL 2000 geändert wurde (weiß ich nicht), aber das ist nicht, was BOL als die Bedeutung von deterministisch definiert.

+0

Martin, danke ... – cshah

+0

Martin, wie kommt NEWID() zurück anderes Ergebnis? – cshah

+0

@cshah - Gute Frage und man weiß nicht die Antwort auf! –