von Markus Winand.

Numerische Strings


Numerische Strings sind Zahlen, die in Text-Feldern gespeichert werden. Obwohl das eine sehr schlechte Design-Praxis ist, kann man einen Index dennoch nutzen, wenn man diese Spalten durchgehend als Text behandelt.

SELECT ...
  FROM ...
 WHERE numeric_string = '42'

Diese Abfrage kann einen Index auf NUMERIC_STRING natürlich nutzen. Wenn man den Vergleich aber mit einer Zahl durchführt, kann die Bedingung nicht mehr als Zugriffsprädikat verwendet werden.

SELECT ...
  FROM ...
 WHERE numeric_string = 42

Beachte die fehlenden Hochkomma. Manche Datenbanken liefern hier einen Fehler (z.B. PostgreSQL), viele führen stattdessen aber einfach eine implizite Konvertierung durch:

SELECT ...
  FROM ...
 WHERE CAST(numeric_string AS INT) = 42

Es ist also dasselbe Problem wie zuvor. Durch die Funktion kann ein Index auf NUMERIC_STRING nicht sinnvoll genutzt werden. Die Lösung ist wieder dieselbe: Anstatt den Spaltentypen an den Suchbegriff anzupassen, passt man den Suchbegriff an den Spaltentypen an:

SELECT ...
  FROM ...
 WHERE numeric_string = CAST(42 AS VARCHAR(10))

Da kann man sich schon fragen, warum es das System nicht anders macht? Das liegt daran, dass das Parsen eines numerischen Strings immer ein eindeutiges Ergebnis liefert. Umgekehrt ist das nicht der Fall. Wenn man eine Zahl als Text darstellt, kann man zum Beispiel Tausender-Separatoren oder führende Nullen verwenden.

42
042
0042
00042
...

Die Datenbank weiß nicht, wie die Zahlen im Textfeld formatiert sind. Daher wird die Konvertierung in die andere Richtung durchgeführt; der Text wird in Zahlen gewandelt – das ist immer eindeutig.

Wenn du diese Seite magst, magst du vielleicht auch …

… meine Newsletter bestellen, gratis Sticker erhalten, mein Buch kaufen oder an einer Schulung teilnehmen.

Bei der Konvertierung mit CAST AS VARCHAR erhält man nur eine String-Repräsen­tation der Zahl. Eine Abfrage liefert dann nur den ersten der oben angeführten Werte. Mit der CAST AS INT-Konvertierung erhält man aber alle Werte. Die beiden Varianten sind also nicht nur aus Performance-Sicht, sondern auch inhaltlich unterschiedlich!

BigQuery 2024-12-18Db2 (LUW) 12.1.2MariaDB 12.0.2MySQL 9.4.0Oracle DB 23.9PostgreSQL 17SQL Server 2022SQLite 3.50.0Keine implizite Konvertierung: Syntax-FehlerCAST(numeric_string AS INT) = 42numeric_string = CAST(42 AS VARCHAR…)

Mit numerischen Strings handelt man sich also zahlreiche Probleme ein. Vor allem die Performance-Probleme bei einer impliziten Konvertierung, aber auch das Risiko von Konvertierungsfehlern, wenn ungültige Zahlen gespeichert sind. Dadurch kann sogar die trivialste Abfrage mit einer Fehlermeldung abbrechen.

Tipp

Verwende numerische Typen, um Zahlen zu speichern.

In die andere Richtung besteht das Problem übrigens nicht.

SELECT ...
  FROM ...
 WHERE numeric_number = '42'

Die Datenbank wird auch hier den String als Zahl interpretieren. Die Konvertierung wird aber nicht auf der Tabellenspalte durchgeführt, die eventuell indiziert sein könnte. Daher kann diese Abfrage einen normalen Index auf NUMERIC_NUMBER nutzen. Manuell kann man die Abfrage dennoch verschleiern, indem man die Konvertierung auf der falschen Seite durchführt:

SELECT ...
  FROM ...
 WHERE TO_CHAR(numeric_number) = '42'
Vorherige SeiteNächste Seite

Du kannst nicht alles an einem Tag lernen. Abonniere den Newsletter via E-Mail, Bluesky oder RSS um sukzessive aufzuholen. Und sieh dir auch modern-sql.com an.

Über den Autor

Foto von Markus Winand

Markus Winand gibt auf modern-sql.com Einblick in SQL und zeigt, wie es von verschiedenen Systemen unterstützt wird. Zuvor machte er use-the-index-luke.com, was er noch immer wartet. Markus kann als Trainer, Sprecher und Berater auf winand.at engagiert werden.

Sein Buch kaufen

Titelbild von „SQL Performance Explained“: Eichhörnchen läuft durchs Grass

Die Essenz: SQL-Tuning auf 200 Seiten

Jetzt Kaufen
(Taschenbuch und/oder PDF)

Sein Training

Markus verwandelt veraltetes SQL-92-Wissen in solides und zeitgemäßes SQL-Know-how

Erfahren Sie mehr»

Neuigkeiten Abonnieren

Markus Winands MailinglistenMarkus Winands RSS-FeedMarkus Winand auf LinkedInMarkus Winand auf XINGMarkus Winand auf TwitterMarkus Winand auf Bluesky
Copyright 2010-2025 Markus Winand. Alle Rechte vorbehalten.
Impressum | Kontakt | KEINE GEWÄHR | Handelsmarken | Datenschutz und DSGVO