Anzahl Einträge einer Tabelle herausfinden => Performance ?
-
Hi,
mal ne Frage an die Datenbank-Experten:
Mit folgendem Statement kann ich mir ja die Anzahl Einträge einer Tabelle geben lassen:
SELECT count(*) AS num_entries FROM MyTableJetzt meine Frage: Wie sieht es bei dieser Anfrage mit der Geschwindigkeit aus?
Werden da intern trotzdem einige Daten dieser Tabelle übertragen und z.B. dann einfach nur gezählt oder geht das sehr fix (wie wenn man den Eintrag z.B. in einer Systemtabelle nachschauen würde) ?
-
Kommt auf viele Dinge an: Datenbanksystem, Treiber, Indizes. Im schlimmsten Fall läuft das so ab, das die Datenbank die Records zählt und dann das Ergebnis zurückschickt. Heutzutage führen allerdings fast alle DBMS interne Statistik-Tabellen oder bekommen die Infos über vorhandene Indizes und geben dann einfach nur den gespeicherten Recordcount zurück. In diesem Fall dauert die Abfrage wenige Millisekunden.
-
Hm ja sowas dachte ich mir fast. Also Zieldatenbank wäre ausschlielich Microsofts SQL Server(2005), deshalb nehme ich mal an, dass da nicht einfach nur die Records gezählt werden? (Wobei ich aber auch davon ausgehen würde, dass für die selbst angelegten Tabellen auch keine selbst angelegeten Indizes existieren)
Gibts da evtl irgendwelche Spezifikationen wo man sowas nachlesen könnte?P.S. Datenbankzugriff erfolgt mittels ADO
-
Äh, habe ich das jetzt richtig verstanden, dass es keine Indizes auf der fraglichen Tabelle gibt? Nicht mal einen Primärindex? Ich kenn den SQL-Server nicht, aber wenn kein Index vorhanden ist, auf den der Select Count ausgeführt werden kann, gehe ich schon davon aus, dass tatsächlich alle Datensätze in der Tabelle durchiteriert werden.
Verwendest Du einen Serverseitigen Cursor, bei den ADO-Verbindungen? Wenn nicht, solltest Du das machen. Dadurch werden solche Abfragen direkt auf dem Server durchgeführt, ohne dass die Tabelle auf den Clientrechner übertragen werden muß.
-
Probiers doch einfach mal aus, der SQL-Server hat doch bestimmt auch ein EXPLAIN oder etwas ähnliches.
-
Naja ich hab halt auch keine so große Datenbank, aber ok theoreitsch müsste man ja auch schon bei kleineren Datenbanken einen Zeitunterschied merken. Wollte hier aber trotzdem erst mal fragen.
Zu Explain: Hab ich noch nie was von gehört (kenn mich auch nicht so wahnsinnig mit DBs aus), aber hab mal gegoogelt und das mssql-pendant dazu ausgeführt. Mit dem Output kann ich nicht wirklich was anfangen
-
Mal so nebenbei: Wofür brauchst das count(*) überhaupt? So eine Abfrage schickt man doch eher selten ab. Wenn du einfach nur die Anzahl Records in einem ADO Recordset wissen willst, dann nutze lieber die ADO Funktion dafür (RecordCount im RecordSet Objekt glaub ich). Der liefert schnell ergebnisse ohne extra Abfrage. Ist aber AFAIK abhängig vom Typ des Recordsets (Sollte Static, Keyset oder sowas sein).
-
Cpp_Junky schrieb:
Ist aber AFAIK abhängig vom Typ des Recordsets (Sollte Static, Keyset oder sowas sein).
Ja das ist vollkommen richtig. Wenn der Cursortype Static oder Keyset ist dann geht das mit RecordCount. Allerdings kommt das für mich aus 2 Gründen nicht in Frage: 1. mache ich mich damit ebend abhängig vom Cursortype (was aber auch nicht wirklich schlimm ist, wenn es entsprechend dokumentiert ist) und 2. (viel wichtiger) benutze ich bisher ForwardOnly, da das eben sehr schnell ist (im Gegensatz zu KeySet z.B.). Ich denke bei entsprechend *großen* Datenbanken macht das dann schon einiges an Performanz aus (aber kann mich auch täuschen, wie gesagt bin jezt nicht unbedingt so der DB-guru )
Cpp_Junky schrieb:
Mal so nebenbei: Wofür brauchst das count(*) überhaupt?
Ja was soll ich sagen... um es kurz zu machen, es hängt mit C-Frickelei zusammen
Aber wenn ich das richtig verstanden habe, dann sollte ein Select Count(*) auf jeden Fall doch spürbar schneller als ein normales select sein. Ich verwende ja z.B. ohnehin schon einen serverseitigen Cursor. Ich hab das jetzt sowieso schon so gut wie implementiert und werd dann einfach mal paar Zeitmessungen machen und schauen wie das aussieht.
Danke für die Antworten auf jeden Fall
-
Schreib dann mal hier rein, was dabei rausgekommen ist
-
So also wenns jetzt noch jemand interessiert, ich hab mal ne Messung gemacht (allerdings ist das keine "professionelle" Messung, die alle bzw. unterschiedliche Umstände usw. berücksichtigt, sondern ziemlich quick&dirty aber für mein Ziel ausreichend genug, deshalb schreib ich hier auch keine genauen Zahlen rein).
Also ich hab ne mittelgroße Tabelle mit 1000 Einträgen genommen. Wenn ich darauf nur ein Select Count(*) ausführe, dann ist das hier bei mir etwa um den Faktor 370 schneller als ein normales Select auf dieser Tabelle. Allerdings ist da der zusätzliche Methoden-Overhead und das Umkopieren in C-Strings nicht berücksichtigt, aber man kann das ja dann selbst pi mal Daumen für sich ungefähr einschätzen. Ist übrigens alles noch in der Debug-Version.