2010-06-25 12 views
17

Ich habe eine Reihe von Anfragen bei der Arbeit bemerkt und auf SO verwenden Einschränkungen in der Form:isnull vs null

isnull(name,'') <> '' 

Gibt es einen bestimmten Grund, warum die Leute das tun und nicht mehr terse

name is not null 

Ist es ein Vermächtnis oder ein Leistungsproblem?

+0

Martin Smith ist richtig, wenn Sie den Code genau angeben. WENN es tatsächlich so etwas wie isnull (name, '') <> @name ist, dann hält man SQL davon ab, einen Index zu verwenden, aber man erhält ein Ergebnis, das mehr wie Donnie beschreibt: – Matt

+0

@Matt: Ja, ich habe einen Fehler gemacht Code gab ich in dem Beispiel. Es ist jetzt behoben. – tgandrews

Antwort

30
where isnull(name,'') <> '' 

entspricht

where name is not null and name <> '' 

der wiederum mit

where name <> '' 

äquivalent ist (wenn Name IS NULL dass endgültigen Ausdruck unbekannt und die Reihe zurück nicht auswerten würde)

Die Verwendung des ISNULL Musters führt zu einem Scan und ist weniger effizient wie im folgenden Test zu sehen ist.

SELECT ca.[name], 
     [number], 
     [type], 
     [low], 
     [high], 
     [status] 
INTO TestTable 
FROM [master].[dbo].[spt_values] 
     CROSS APPLY (SELECT [name] 
        UNION ALL 
        SELECT '' 
        UNION ALL 
        SELECT NULL) ca 


CREATE NONCLUSTERED INDEX IX_TestTable ON dbo.TestTable(name) 

GO 


SELECT name FROM TestTable WHERE isnull(name,'') <> '' 

SELECT name FROM TestTable WHERE name is not null and name <> '' 
/*Can be simplified to just WHERE name <> '' */ 

Welches sollte Ihnen den Ausführungsplan geben, den Sie benötigen.

enter image description here

+0

"Die Verwendung dieses Musters ... ist weniger effizient ..." Das Muster ist die Verwendung von ISNULL oder der IS NULL ... ODER = Konstrukt? –

+1

@KarlKieninger - Das Muster ist die Verwendung von 'ISNULL' - ursprünglich gab es einige Ausführungsplanbilder, die das klarer machten. Wird sie regenerieren .. –

2

isnull(name,'') <> :name ist eine Abkürzung für (name is null or name <> :name) (unter der Annahme, dass :name nie die leere Zeichenfolge enthält, weshalb Shorthands so schlecht sein kann).

Leistungsmäßig hängt es davon ab. or Anweisungen in where Klauseln können extrem schlechte Leistung geben. Funktionen auf Spalten beeinträchtigen jedoch die Indexnutzung. Wie immer: Profil.

+0

'(Name ist null oder '' <>: name)' .... nein? –

1

Nun kann ich sie sehen, die dies verwenden, weil auf diese Weise, wenn der Name nicht übereinstimmt oder null ist, es als ein fehlgeschlagener Vergleich zurückgibt. Das bedeutet wirklich: name is null oder name <> name

Wo wie dieser name is not null nur überprüft, ob der Name Null ist.

12
is not null 

Wird nur überprüfen, wenn das Feld nicht null ist. Wenn das Feld eine leere Zeichenfolge enthält, ist das Feld nicht länger null.

isnull(name, '') <> name 

Prüft auf eine leere und eine leere Zeichenfolge.

1

Sie bedeuten nicht das Gleiche.

name is not null 

Diese prüft, ob Datensätze, in denen der Name Feld

isnull(name,'') <> name 

Dieses man den Wert von Null-Felder auf die leere Zeichenfolge ändert, so dass sie in einem Vergleich null verwendet werden kann. In SQL Server (aber nicht in Oracle denke ich), wenn ein Wert Null ist und es verwendet wird, um Equlaity oder Ungleichheit zu vergleichen, wird es nicht berücksichtigt, weil Null bedeutet, dass ich den Wert nicht kenne und somit kein tatsächlicher Wert ist.Wenn Sie also sicherstellen möchten, dass die Nullsätze beim Vergleich berücksichtigt werden, benötigen Sie ISNULL oder COALESCE (was der ASCII-STANDARD-Ausdruck ist, der verwendet wird, da ISNULL nicht in allen Datenbanken funktioniert).

Was sollten Sie suchen ist die differnece zwischen

isnull(a.name,'') <> b.name 

a.name <> b.name

dann werden Sie verstehen, warum die ISNULL benötigt wird, korrekte Ergebnisse zu erhalten.

1

Ich habe anscheinend Ihre Frage falsch gelesen. Also ich meine erste Antwort ließ schlagen und versuchen, diese ein:

isnull(name,'') <> '' 

ist eine irrige Abkürzung für

name is not null and name <> '' 
0

Auch wenn Sie die Verwendung des Index auf dieser Spalte machen möchten, verwenden Sie

name is not null and name <> '' 
1

Andere haben auf den funktionellen Unterschied hingewiesen. Was das Leistungsproblem betrifft, so habe ich in Postgres festgestellt, dass Postgres eine Funktion "coalesce" hat, die dem "isnull" entspricht, das in einigen anderen SQL-Dialekten zu finden ist - aber in Postgres

where coalesce(foobar,'')='' 

ist deutlich schneller als

where foobar is null or foobar='' 

auch kann es awesomely

where foobar>'' 

über

zu sagen dramatisch schneller

Ein Größer-als-Test kann den Index verwenden und damit alle Leerzeichen überspringen, während ein ungleicher Test eine vollständige Datei lesen muss. (Angenommen, Sie haben einen Index für das Feld, und kein anderer Index wird bevorzugt verwendet.)

0

Diese beiden Abfragen sind nicht identisch. Zum Beispiel habe ich keinen zweiten Vornamen haben, ist dies eine bekannte Tatsache, die als

gespeichert werden können
MiddleName='' 

Wenn wir jedoch, nicht jemand mittleren Namen kennen, können wir NULL speichern. Also ISNULL (MiddleName, '') bedeutet "Personen ohne bekannte zweite Vornamen".

0

Es ist sowohl die leere Zeichenfolge und NULL zu behandeln. Während es gut ist, mit einer Aussage umzugehen, ist proprietäre Syntax. Ich würde dies mit Portable Standard SQL als

schreiben
NULLIF(name, '') IS NOT NULL