webentwicklung-frage-antwort-db.com.de

SQL: Wie man richtig prüft, ob ein Datensatz existiert?

In der Dokumentation zu SQL Tuning habe ich Folgendes gefunden:

Select count(*):
- Zählt die Anzahl der Zeilen
- Wird häufig falsch verwendet, um die Existenz eines Datensatzes zu überprüfen

Ist Select count(*) wirklich so schlimm? 

Wie kann ich das Vorhandensein eines Datensatzes überprüfen?

164
systempuntoout

Es ist besser, eine der folgenden Möglichkeiten zu verwenden:

-- Method 1.
SELECT 1
FROM table_name
WHERE key = value;

-- Method 2.
SELECT COUNT(1)
FROM table_name
WHERE key = value;

Die erste Alternative sollte kein Ergebnis oder ein Ergebnis liefern, die zweite Zählung sollte Null oder Eins sein.

Wie alt ist die von Ihnen verwendete Dokumentation? Obwohl Sie gute Ratschläge gelesen haben, optimieren die meisten Abfrageoptimierer in den aktuellen RDBMS-Systemen SELECT COUNT(*) ohnehin. Obwohl es theoretisch einen Unterschied gibt (und ältere Datenbanken), sollten Sie in der Praxis keinen Unterschied feststellen.

202

Ich würde es vorziehen, die Count-Funktion überhaupt nicht zu verwenden:

IF [NOT] EXISTS ( SELECT 1 FROM MyTable WHERE ... )
     <do smth>

Wenn Sie beispielsweise prüfen möchten, ob ein Benutzer vorhanden ist, bevor Sie ihn in die Datenbank einfügen, kann die Abfrage folgendermaßen aussehen:

IF NOT EXISTS ( SELECT 1 FROM Users WHERE FirstName = 'John' AND LastName = 'Smith' )
BEGIN
    INSERT INTO Users (FirstName, LastName) VALUES ('John', 'Smith')
END
164

Sie können verwenden:

SELECT 1 FROM MyTable WHERE <MyCondition>

Wenn kein Datensatz mit der Bedingung übereinstimmt, ist das resultierende Recordset leer.

18

Die anderen Antworten sind ziemlich gut, aber es wäre auch nützlich, LIMIT 1 (oder das Äquivalent ) hinzuzufügen, um die Überprüfung unnötiger Zeilen zu verhindern.

12
JesseW

Sie können verwenden:

SELECT COUNT(1) FROM MyTable WHERE ... 

oder

WHERE [NOT] EXISTS 
( SELECT 1 FROM MyTable WHERE ... )

Dies ist effizienter als SELECT *, da Sie einfach den Wert 1 für jede Zeile und nicht alle Felder auswählen.

Es gibt auch einen kleinen Unterschied zwischen COUNT (*) und COUNT (Spaltenname):

  • COUNT(*) zählt alle Zeilen einschließlich Nullen
  • COUNT(column name) zählt nur keine NULL-Vorkommen des Spaltennamens
10
Winston Smith
SELECT COUNT(1) FROM MyTable WHERE ...

wird alle Datensätze durchlaufen. Dies ist der Grund, warum es für die Existenz von Datensätzen schlecht ist.

Ich würde ... benutzen

SELECT TOP 1 * FROM MyTable WHERE ...

Nachdem Sie einen Datensatz gefunden haben, wird die Schleife beendet.

7
oski

Sie können verwenden:

SELECT 1 FROM MyTable WHERE... LIMIT 1

Verwenden Sie select 1, um die Überprüfung nicht benötigter Felder zu verhindern.

Verwenden Sie LIMIT 1, um die Überprüfung nicht benötigter Zeilen zu verhindern.

6
user3059943

Andere Option:

SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [MyTable] AS [MyRecord])
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END
0
Pranav

Ich verwende diesen Weg:

IIF(EXISTS (SELECT TOP 1 1 
                FROM Users 
                WHERE FirstName = 'John'), 1, 0) AS DoesJohnExist
0
DiPix