Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi [MySQL]existenz eines datensatzes prüfen: was ist schneller? (https://www.delphipraxis.net/66200-%5Bmysql%5Dexistenz-eines-datensatzes-pruefen-ist-schneller.html)

Aenogym 26. Mär 2006 15:34

Datenbank: MySQL • Version: 5 • Zugriff über: Zeos

[MySQL]existenz eines datensatzes prüfen: was ist schneller?
 
hi ihr,

der titel ist vielleicht etwas unschön gewählt.
ich habe meine tabelle "accounts" (typ MyISAM). struktur:
Code:
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
`pass` varchar(32) NOT NULL,
`online` enum('1','0') NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
jetzt möchte ich prüfen, ob ein eintrag für einen bestimmten user existiert. da die tabelle sehr viele datensätze enthalten wird, suche ich die schnellste methode. bisher mache ich es so:
SQL-Code:
SELECT id FROM accounts WHERE name = 'max_mustermann' LIMIT 1
dann prüfe ich einfach, ob ich eine zeile erhalten habe. andererseits könnte ich ja auch folgendes abfragen:
SQL-Code:
SELECT count(*) FROM accounts WHERE name = 'max_mustermann'
wenn count(*) dann 1 ist, hab ich eine zeile.

meine frage ist jetzt, welches die schnellste methode ist, den datensatz auf existenz zu prüfen (vielleicht habt ihr ja noch ganz andere herangehensweisen - ich bin da sehr offen ;))

danke schonmal,
aenogym

Chewie 26. Mär 2006 15:55

Re: [MySQL]existenz eines datensatzes prüfen: was ist schnel
 
Also zuallererst: Leg mal einen Index auf die Namens-Spalte an. Da du diese als Selektionskriterium nimmst, spart das schon mal einen Haufen Zeit bei den Lesezugriffen (das Schreibzugriffe dauern dafür länger).

Ich bin nicht sicher, wann LIMIT ausgeführt wird. Bestenfalls wird nach dem ersten Vorkommen aufgehört zu suchen, dann ist die Variante mit LIMIT die schnellste. Schlimmestenfalls werden alle gefunden und dann erst LIMIT ausgeführt. Im Mysql-Manual sollte aber drin stehen, in welcher Reihenfolge die einzelnen Klauseln ausgeführt werden.

Falls LIMIT, wie oben angesprochen, erst am Ende ausgeführt werden sollte, dann würde ich die Variante mit dem COUNT empfehlen, sonst die mit dem LIMIT. Der Index tut aber in beiden Fällen gut.


Edit: Ich sehe gerade, name ist UNIQUE - könnte gut sein, dass UNIQUE einen normalen Index miteinschließt, ich bin nicht sicher.

alcaeus 26. Mär 2006 16:07

Re: [MySQL]existenz eines datensatzes prüfen: was ist schnel
 
Zitat:

Zitat von Chewie
Ich bin nicht sicher, wann LIMIT ausgeführt wird. Bestenfalls wird nach dem ersten Vorkommen aufgehört zu suchen, dann ist die Variante mit LIMIT die schnellste. Schlimmestenfalls werden alle gefunden und dann erst LIMIT ausgeführt. Im Mysql-Manual sollte aber drin stehen, in welcher Reihenfolge die einzelnen Klauseln ausgeführt werden.

Leider werden die Limits erst nach dem Selektieren aller zutreffenden Datensaetze angewandt. Das heisst, wenn 2000 Datensaetze auf deine Bedingung zutreffen, dann werden die erstmal alle rausgeholt. Anschliessend wird alles, was du nicht brauchst, weggeworfen. Kann sein dass sich das geaendert hat/noch aendert; in mySQL4 ist es aber definitiv noch so.

Aber auch das count(*) ist nicht optimal. Du solltest count(<idfeld>) verwenden; dies spart zeit.

Greetz
alcaeus

Chewie 26. Mär 2006 16:09

Re: [MySQL]existenz eines datensatzes prüfen: was ist schnel
 
Zitat:

Zitat von alcaeus
Aber auch das count(*) ist nicht optimal. Du solltest count(<idfeld>) verwenden; dies spart zeit.

Ist das bei COUNT nicht egal? Das DBMS sollte doch erkennen, dass die Spalte in einer Aggregatfunktion verwendet wird, der egal ist, auf welche Spalten sie angewandt wird, oder nicht?

alcaeus 26. Mär 2006 16:12

Re: [MySQL]existenz eines datensatzes prüfen: was ist schnel
 
Zitat:

Zitat von Chewie
Ist das bei COUNT nicht egal? Das DBMS sollte doch erkennen, dass die Spalte in einer Aggregatfunktion verwendet wird, der egal ist, auf welche Spalten sie angewandt wird, oder nicht?

Anscheinend nicht. Ich hab dies nie genauer nachvollzogen, aber es mal irgendwo gelesen und manchmal auch schon selbst bemerkt.

Greetz
alcaeus

marabu 26. Mär 2006 16:21

Re: [MySQL]existenz eines datensatzes prüfen: was ist schnel
 
Count(*) ist ein wunderbares Tuning-Mittel - wenn keine WHERE-Klausel verwendet wird. Da MySQL 4 noch keinen Existenz-Operator unterstützt, halte ich die erste Variante für die Beste - allerdings macht LIMIT 1 bei einem UNIQUE INDEX keinen Sinn.

Grüße vom marabu

Aenogym 26. Mär 2006 17:53

Re: [MySQL]existenz eines datensatzes prüfen: was ist schnel
 
@marabu: das mit dem LIMIT und dem UNIQUE INDEX stimmt irgendwie :oops:
und dass count(*) äußerst optimiert ist, wenn WHERE nicht zum einsatz kommt habe ich auch schon gelesen. nur leider brauche ich ja das where...

also ich habe jetzt meine 'id'-spalte rausgeschmissen (ist überflüssig, da die nutzernamen auch eindeutig sein sollen -> PRIMARY gemacht). und abfragen tu ich das ganze jetzt mit SELECT count(name) FROM accounts WHERE name = 'max'. bin recht zufrieden damit :)

danke euch allen!
aeno

alcaeus 26. Mär 2006 18:51

Re: [MySQL]existenz eines datensatzes prüfen: was ist schnel
 
Zitat:

Zitat von Aenogym
also ich habe jetzt meine 'id'-spalte rausgeschmissen (ist überflüssig, da die nutzernamen auch eindeutig sein sollen -> PRIMARY gemacht). und abfragen tu ich das ganze jetzt mit SELECT count(name) FROM accounts WHERE name = 'max'. bin recht zufrieden damit :)

Wenn du Abfragen ueber den Namen machst, dann lege einen Index auf die Namen-Spalte; aufgrund der Normalisierung solltest du (wenn die Benutzerdaten in anderen Tabellen benoetigt werden) etwas eindeutiges verwenden; wenn jemand seinen Nutzernamen aendern moechte, dann hast du ein Problem mit deiner Methode (es sei denn du verhinderst das Aendern komplett)

Greetz
alcaeus

Aenogym 27. Mär 2006 15:45

Re: [MySQL]existenz eines datensatzes prüfen: was ist schnel
 
ja, ich habe die name-spalte als primärindex definiert. und ja, eine änderung des namens ist nicht möglich :)

aeno


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz