it-swarm.com.de

Auswirkungen auf die Leistung von MySQL VARCHAR-Größen

Gibt es in MySQL einen Leistungsunterschied zwischen den Varchar-Größen? Zum Beispiel varchar(25) und varchar(64000). Wenn nicht, gibt es einen Grund, nicht alle Varchars mit der maximalen Größe zu deklarieren, um sicherzustellen, dass Ihnen nicht der Platz ausgeht?

46
BenV

Sie müssen die Kompromisse bei der Verwendung von CHAR gegen VARCHAR erkennen

Mit CHAR-Feldern weisen Sie genau das zu, was Sie erhalten. Beispielsweise weist CHAR (15) 15 Bytes zu und speichert sie, unabhängig davon, wie viele Zeichen Sie in das Feld einfügen. Die Manipulation von Zeichenfolgen ist einfach und unkompliziert, da die Größe des Datenfelds vollständig vorhersehbar ist.

Mit VARCHAR-Feldern erhalten Sie eine ganz andere Geschichte. Zum Beispiel weist VARCHAR (15) tatsächlich dynamisch bis zu 16 Bytes zu, bis zu 15 für Daten und mindestens 1 zusätzliches Byte, um die Länge der Daten zu speichern. Wenn Sie die Zeichenfolge 'Hallo' speichern müssen, die 6 Bytes und nicht 5 Bytes benötigt, muss die Zeichenfolgenmanipulation in jedem Fall eine Längenprüfung durchführen.

Der Kompromiss ist offensichtlicher, wenn Sie zwei Dinge tun:
1. Millionen oder Milliarden von Zeilen speichern
2. Indizierungsspalten, die entweder CHAR oder VARCHAR sind

TRADEOFF # 1

Offensichtlich hat VARCHAR den Vorteil, dass Daten mit variabler Länge kleinere Zeilen und damit kleinere physische Dateien erzeugen würden.

TRADEOFF # 2

Da CHAR-Felder aufgrund fester Feldbreiten weniger Zeichenfolgenmanipulation erfordern, sind Indexsuchen für CHAR-Felder im Durchschnitt 20% schneller als für VARCHAR-Felder. Dies ist keine Vermutung von meiner Seite. Das Buch MySQL Database Design and Tuning hat auf einer MyISAM-Tabelle etwas Wunderbares geleistet, um dies zu beweisen. Das Beispiel im Buch hat ungefähr Folgendes bewirkt:

ALTER TABLE tblname ROW_FORMAT=FIXED;

Diese Direktive zwingt VARCHARs dazu, sich als CHARs zu verhalten. Ich habe dies bei meinem vorherigen Job im Jahr 2007 getan und eine 300-GB-Tabelle erstellt und die Indexsuche um 20% beschleunigt, ohne etwas anderes zu ändern. Es hat wie veröffentlicht funktioniert. Es wurde zwar ein Tisch mit fast doppelter Größe hergestellt, aber das geht einfach auf Kompromiss Nr. 1 zurück.

Sie können die gespeicherten Daten analysieren, um festzustellen, was MySQL für die Spaltendefinition empfiehlt. Führen Sie einfach Folgendes für eine beliebige Tabelle aus:

SELECT * FROM tblname PROCEDURE ANALYSE();

Dadurch wird die gesamte Tabelle durchlaufen und Spaltendefinitionen für jede Spalte basierend auf den darin enthaltenen Daten, den minimalen Feldwerten, den maximalen Feldwerten usw. empfohlen. Manchmal muss man bei der Planung von CHAR vs VARCHAR nur den gesunden Menschenverstand verwenden. Hier ist ein gutes Beispiel:

Wenn Sie IP-Adressen speichern, besteht die Maske für eine solche Spalte aus höchstens 15 Zeichen (xxx.xxx.xxx.xxx). Ich würde sofort zu CHAR (15) springen, da die Länge der IP-Adressen nicht allzu stark variiert und die zusätzliche Komplexität der String-Manipulation durch ein zusätzliches Byte gesteuert wird. Sie können immer noch eine PROCEDURE ANALYZE () für eine solche Spalte durchführen. Es kann sogar VARCHAR empfehlen. In diesem Fall wäre mein Geld immer noch für CHAR über VARCHAR.

CHAR vs VARCHAR-Probleme können nur durch ordnungsgemäße Planung gelöst werden. Mit großer Kraft geht große Verantwortung einher (Klischee aber wahr)

30
RolandoMySQLDBA

Die Antwort darauf ist eigentlich ziemlich komplex. Die Kurzversion: es gibt einen Unterschied.

  1. Beim Erstellen temporärer Tabellen zum Filtern von Ergebnissen (z. B. GROUP BY Anweisungen) wird die volle Länge zugewiesen.

  2. Das Drahtprotokoll (Senden von Zeilen an den Client) weist wahrscheinlich die größere Länge zu.

  3. Die Speicher-Engine kann/kann möglicherweise keinen geeigneten Varchar implementieren.

Für (2) Ich gebe zu, dass das Drahtprotokoll nicht etwas ist, mit dem ich bestens vertraut bin, aber der allgemeine Rat hier ist, zumindest einen minimalen Aufwand zu betreiben, um die Länge zu erraten.

13
Morgan Tocker

Die meisten Antworten in diesem Thread sind fünf Acht Jahre alt, geschrieben vor InnoDB und utf8 waren Standardeinstellungen. Also, lass mich von vorne anfangen ...

Wenn eine Abfrage eine interne temporäre Tabelle benötigt, versucht sie, eine MEMORY -Tabelle zu verwenden. Aber MEMORY kann nicht verwendet werden, wenn

  • TEXT/BLOB Spalten werden abgerufen, sogar TINYTEXT.
  • VARCHAR größer als ein Betrag, wahrscheinlich 512 in der aktuellen Version.

Beachten Sie außerdem, dass VARCHARs in CHARs umgewandelt wird. (8.0 ändert dies.) VARCHAR(255) mit einem CHARACTER SET utf8 Wird also auf 765 Byte erweitert, unabhängig davon, was sich in der Spalte befindet. Dann könnte dies ausgelöst werden:

  • Wenn die Tabelle MEMORY größer als max_heap_table_sizeodertmp_table_size Wird, wird sie in MyISAM konvertiert und möglicherweise auf die Festplatte übertragen.

Es ist also wahrscheinlicher, dass VARCHAR(25)MEMORY bleibt und daher schneller ist. (255) Ist nicht so gut und (64000) Ist schlecht.

(In Zukunft werden temporäre Tabellen wahrscheinlich InnoDB sein, und ein Teil dieser Antwort muss überarbeitet werden.)

11
Rick James

Eine varchar-Spalte dieser Größe erhöht die Wahrscheinlichkeit, dass Abfragen in der gesamten Tabelle temporäre Tabellen verwenden. Laut dem High Performance MySQL-Buch. Wenn das Optimierungsprogramm versucht, festzustellen, ob es diese Abfrage im Speicher ausführen kann oder ob es eine temporäre Tabelle benötigt, überprüft es die Zeilengröße basierend auf der Tabellendefinition. Dies bedeutet, dass es aus Gründen der Geschwindigkeit nicht versucht, die Anzahl der 64-KB-Zeichen zu ermitteln Sie verwenden tatsächlich. Aus diesem Grund empfehlen die Autoren, diese Definition nicht weit über die tatsächlich möglichen Werte in der Spalte hinaus auszudehnen. Wenn Sie sich auf weitere Abfragen in temporären Tabellen einstellen (auch wenn die tatsächliche Datengröße in den Arbeitsspeicher passen könnte), sind Ihnen jetzt E/A-Strafen entstanden, die Sie hätten vermeiden können.

6
TechieGurl

Nach meinem Verständnis können die kleineren Felder direkt in den Index aufgenommen werden, die längeren nicht. Wenn Sie möchten, dass die Zeichenfolgen indizierbar sind, sollten Sie sie aufgrund dieser Einschränkung kürzer halten. Andernfalls, nein, da sie beide varchar sind, funktionieren Operationen wie Sortieren oder Vergleichen in der gleichen Zeit, unabhängig davon, ob die Felder 25 oder MAX sind.

5
jcolebrand

stellen Sie sicher, dass Ihnen nicht der Raum ausgeht

Dieser Satz impliziert, dass Sie die Frage stellen, weil Sie sich nicht sicher sind, welche Daten Sie in der Datenbank speichern werden. Wenn dies zutrifft, können Sie dies so schnell wie möglich herausfinden, da Sie dies für die Kapazitätsplanung benötigen. Wenn Sie beispielsweise Datenelemente mit 7000 Zeichen erhalten, müssen Sie dies wissen, da dies Auswirkungen auf die Leistung eines DBMS haben würde.

Trotzdem bevorzuge ich Spaltengrößen, die sich auf den erwarteten Inhalt beziehen. Beispielsweise ist es unwahrscheinlich, dass eine Telefonnummer länger als 50 Zeichen ist, selbst wenn Sie eine Landesvorwahl und eine Nebenstelle angeben. Ebenso besteht eine Postleitzahl höchstwahrscheinlich aus 20 Zeichen oder weniger.

3
Larry Coleman