Frage

Zwischen utf8_general_ci und utf8_unicode_ci, gibt es Unterschiede in Bezug auf die Leistung?

War es hilfreich?

Lösung

Diese beiden Sortierungen sind sowohl für die UTF-8-Zeichenkodierung. Die Unterschiede sind in, wie Text sortiert und verglichen wird.

Hinweis: Da MySQL 5.5.3 sollten Sie utf8mb4 statt utf8. Beide beziehen sich auf die UTF-8-Codierung, aber die ältere utf8 hatte eine MySQL-spezifische Beschränkung Verwendung von Zeichen verhindert oben 0xFFFD nummeriert.

Die wichtigsten Unterschiede

  • utf8mb4_unicode_ci ist für die universelle Sortierung und Vergleich zu den offiziellen Unicode-Regeln basieren, die genau in einer Vielzahl von Sprachen sortieren.

  • utf8mb4_general_ci ist eine vereinfachte Satz Regeln des Sortierens, die ebenso wie er kann tun soll, während viele Short-Cuts entwickelt unter Geschwindigkeit zu verbessern. Es ist nicht den Unicode-Regeln folgen und zu einem unerwünschten Sortierung oder Vergleich in einigen Situationen, wie zum Beispiel bei der Verwendung von bestimmten Sprachen oder Zeichen führen.

    Auf modernen Servern, wird diese Leistungssteigerung alle aber vernachlässigbar. Es wurde in einer Zeit entwickelt, als Server einen winzigen Bruchteil der CPU-Leistung heutiger Computer hatte.

Hinweis: Es existiert nun eine aktualisierte Version von utf8mb4_unicode_ci utf8mb4_0900_ai_ci genannt - diese basiert auf Änderungen in Unicode Version 9.0, und ist offenbar auch schneller. Es nimmt ein neues Benennungsschema wobei 0900 die Version Unicode ist und ai bedeutet Akzent unempfindliche -. Wie der vorherige utf8mb4_unicode_ci, Akzente in Buchstaben sind nicht signifikant angesehen

Vorteile von utf8mb4_unicode_ci über utf8mb4_general_ci

utf8mb4_unicode_ci, die die Unicode-Regeln für die Sortierung und den Vergleich verwendet, verwendet einen ziemlich komplexen Algorithmus für die korrekte Sortierung in einer Vielzahl von Sprachen, und wenn eine große Auswahl an Sonderzeichen verwenden. Diese Regeln müssen Berücksichtigung sprachspezifische Konventionen zu übernehmen; nicht alle sortiert ihre Charaktere in dem, was wir ‚alphabetischer Reihenfolge.‘

nennen würde

Was Latein (dh „europäische“) Sprachen gehen, gibt es nicht viel Unterschied zwischen dem Unicode ist das Sortieren und die vereinfachte utf8mb4_general_ci in MySQL Sortierung, aber es gibt noch ein paar Unterschiede:

  • Für die Beispiele, die Unicode-Sortier Sorten „ß“ wie „ss“ und „oe“ wie „OE“, wie Leute, die diese Zeichen verwenden normalerweise wollen würde, während utf8mb4_general_ci sie als einzelne Zeichen sortiert (vermutlich wie „s "und "e" bezeichnet).

  • Einige Unicode-Zeichen werden als ignorable definiert, das heißt, sie nicht auf die Sortierreihenfolge und der Vergleich sollte stattdessen auf das nächste Zeichen bewegen sich verlassen sollte. utf8mb4_unicode_ci behandelt diese richtig.

In nicht-lateinischen Sprachen wie asiatische Sprachen oder Sprachen mit verschiedenen Alphabeten, kann es eine Menge mehr Unterschiede zwischen Unicode-Sortierung und der vereinfachten utf8mb4_general_ci Sortierung sein. Die Eignung der utf8mb4_general_ci hängt stark von der verwendeten Sprache. Für einige Sprachen, wird es völlig unzureichend sein.

Was sollten Sie verwenden?

Es ist mit ziemlicher Sicherheit kein Grund mehr zu verwenden utf8mb4_general_ci, wie wir hinter dem Punkt verlassen haben, wo die CPU-Geschwindigkeit niedrig genug ist, dass der Unterschied in der Leistung wichtig sein würde. Ihre Datenbank wird mit ziemlicher Sicherheit durch andere Engpässe als diese begrenzt werden.

In der Vergangenheit empfohlen einige Leute utf8mb4_general_ci außer zu verwenden, wenn eine genaue Sortierung wichtig genug sein würde, die Leistung Kosten zu rechtfertigen. Heute ist diese Leistung gekostet hat so gut wie verschwunden, und Entwickler behandeln Internationalisierung mehr ernst.

Es gibt ein Argument gemacht werden, dass, wenn die Geschwindigkeit als die Genauigkeit ist Ihnen wichtiger ist, können Sie auch keine Sortierung bei allen Produkten. Es ist trivial ein machenAlgorithmus schneller, wenn Sie brauchen es nicht genau. So utf8mb4_general_ci ist ein Kompromiss, der wahrscheinlich nicht aus Geschwindigkeitsgründen erforderlich und wahrscheinlich auch nicht geeignet für die Richtigkeit Gründe.

Eine andere Sache, die ich hinzufügen, ist, dass selbst wenn Sie Ihre Anwendung kennen nur die englische Sprache unterstützt, kann es nach wie vor mit Personennamen befassen muß, die oft Zeichen in anderen Sprachen verwendet werden, enthalten können, in denen es genauso wichtig ist, richtig zu sortieren. hilft unter Verwendung der Unicode-Regeln für allen Seelenfrieden hinzufügen, dass die sehr intelligenten Unicode Menschen Arbeit richtig zu machen Sortierung sehr hart gearbeitet haben, zu.

Was die Teile bedeuten

Zum einen ci ist für Groß- und Kleinschreibung Sortieren und Vergleich. Dies bedeutet, es für Textdaten geeignet ist, und Fall ist nicht wichtig. Die anderen Typen von Sortier sind cs (Groß-) für Textdaten in dem Fall wichtig ist, und bin, denn wo die Codierung Bedürfnisse anzupassen, Bit für Bit, die für Felder geeignet ist, die wirklich binäre Daten (einschließlich codiert sind, für Beispiel Base64). Case-sensitive Sortierung führt zu einigen seltsamen Resultaten und case-sensitive Vergleich kann in doppelte Werte ergeben sich nur in Groß- und Kleinschreibung, so Groß- und Sortierungen fallen aus Bevorzugung für Textdaten - wenn Fall zu Ihnen wichtig ist, dann sonst ignorable Interpunktion und so weiter ist wahrscheinlich auch signifikant, und eine binäre Sortierung könnte besser geeignet sein.

Als nächstes unicode oder general bezieht sich auf die spezifischen Sortier- und Vergleichsregeln - insbesondere die Art und Weise Text normiert oder verglichen. Es gibt viele verschiedene Arten von Regeln für die utf8mb4 Zeichencodierung, mit unicode und general zwei zu sein, die in allen möglichen Sprachen statt einem spezifischen zu arbeiten gut versuchen. Die Unterschiede zwischen diesen beiden Regelungen sind Gegenstand dieser Antwort. Beachten Sie, dass neuere Regelsätze 0900 umfassen unter Bezugnahme auf Unicode 9.0 und unicode_520 auf Unicode 5.2 Bezug genommen wird.

Und schließlich ist utf8mb4 natürlich die Zeichenkodierung intern verwendet. In dieser Antwort spreche ich nur über Unicode basierte Kodierungen.

Andere Tipps

wollte ich wissen, was der Performance-Unterschied ist utf8_general_ci und utf8_unicode_ci zwischen der Verwendung, aber ich habe kein Benchmarks im Internet aufgelistet, so habe ich beschlossen, Benchmarks selbst zu erstellen.

Ich habe eine sehr einfache Tabelle mit 500.000 Zeilen:

CREATE TABLE test(
  ID INT(11) DEFAULT NULL,
  Description VARCHAR(20) DEFAULT NULL
)
ENGINE = INNODB
CHARACTER SET utf8
COLLATE utf8_general_ci;

Dann füllte ich es mit zufälligen Daten durch diese gespeicherte Prozedur ausgeführt wird:

CREATE PROCEDURE randomizer()
BEGIN
  DECLARE i INT DEFAULT 0;
  DECLARE random CHAR(20) ;
  theloop: loop
    SET random = CONV(FLOOR(RAND() * 99999999999999), 20, 36);
    INSERT INTO test VALUES (i+1, random);
    SET i=i+1;
    IF i = 500000 THEN
      LEAVE theloop;
    END IF;
  END LOOP theloop;
END

Dann habe ich die folgenden gespeicherten Prozeduren zur Benchmark einfachen SELECT, SELECT mit LIKE und Sortieren (SELECT mit ORDER BY):

CREATE PROCEDURE benchmark_simple_select()
BEGIN
  DECLARE i INT DEFAULT 0;
  theloop: loop
    SELECT *
    FROM test
    WHERE Description = 'test' COLLATE utf8_general_ci;
    SET i = i + 1;
    IF i = 30 THEN
      LEAVE theloop;
    END IF;
  END LOOP theloop;
END;

CREATE PROCEDURE benchmark_select_like()
BEGIN
  DECLARE i INT DEFAULT 0;
  theloop: loop
    SELECT *
    FROM test
    WHERE Description LIKE '%test' COLLATE utf8_general_ci;
    SET i = i + 1;
    IF i = 30 THEN
      LEAVE theloop;
    END IF;
  END LOOP theloop;
END;

CREATE PROCEDURE benchmark_order_by()
BEGIN
  DECLARE i INT DEFAULT 0;
  theloop: loop
    SELECT *
    FROM test
    WHERE ID > FLOOR(1 + RAND() * (400000 - 1))
    ORDER BY Description COLLATE utf8_general_ci LIMIT 1000;
    SET i = i + 1;
    IF i = 10 THEN
      LEAVE theloop;
    END IF;
  END LOOP theloop;
END;

Bei den gespeicherten Prozeduren über utf8_general_ci Kollatierung verwendet wird, aber natürlich bei den Tests verwendete ich sowohl utf8_general_ci und utf8_unicode_ci.

rief ich jede gespeicherte Prozedur 5 mal für jeden Vergleich (5-mal für utf8_general_ci und 5-mal für utf8_unicode_ci) und dann die Mittelwert berechnet.

Meine Ergebnisse sind:

benchmark_simple_select()

  • mit utf8_general_ci: 9957 ms
  • mit utf8_unicode_ci: 10.271 ms

In dieser Benchmark mit utf8_unicode_ci langsamer als utf8_general_ci um 3,2%.

benchmark_select_like()

  • mit utf8_general_ci: 11.441 ms
  • mit utf8_unicode_ci: 12.811 ms

In dieser Benchmark mit utf8_unicode_ci ist langsamer als utf8_general_ci um 12%.

benchmark_order_by()

  • mit utf8_general_ci: 11.944 ms
  • mit utf8_unicode_ci: 12.887 ms

In dieser Benchmark mit utf8_unicode_ci langsamer als utf8_general_ci um 7,9%.

Dieser Beitrag es beschreibt sehr schön.

Kurz gesagt:. Utf8_unicode_ci verwendet den Unicode Kollatierungsalgorithmus wie in den Unicode-Standards definiert, während utf8_general_ci eine einfache Sortierreihenfolge, die in „ungenauen“ Sortierergebnissen

Sehen Sie das MySQL-Handbuch, Unicode-Zeichensätze Abschnitt:

  

Für alle Unicode-Zeichensatz,   Operationen durchgeführt die Verwendung von   _general_ci Sortierungs sind schneller als die für die _unicode_ci Sortierung.   Zum Beispiel Vergleiche für die   utf8_general_ci Sortierungs sind schneller,   aber etwas weniger korrekt, als   Vergleiche für utf8_unicode_ci. Das   Grund dafür ist, dass   utf8_unicode_ci unterstützt Mappings solchen   als Erweiterungen; das heißt, wenn man   Zeichen vergleicht als gleich   Kombinationen von anderen Zeichen. Zum   zB in der deutschen und einige andere   Sprachen „ß“ ist gleich „ss“.   utf8_unicode_ci unterstützt auch   Kontraktionen und vernachlässigbares Zeichen.   utf8_general_ci ist ein Vermächtnis Sortierungs   dass keine Unterstützung für Erweiterungen,   Kontraktionen oder ignorable Zeichen.   Es kann nur eins-zu-eins machen   zwischen den Zeichen Vergleiche.

Um es zusammenzufassen, utf_general_ci verwendet eine kleinere und weniger korrekt ist (nach der Norm) Satz von Vergleichen als utf_unicode_ci die sollte die gesamte Standard implementieren. Die general_ci Set wird schneller sein, weil es weniger Berechnung zu tun.

Kurz Worten:

Wenn Sie besser brauchen Sortierreihenfolge - Verwendung utf8_unicode_ci (dies ist die bevorzugte Methode),

aber wenn man ganz interessiert an Leistung -. Verwendung utf8_general_ci, aber weiß, dass es ein wenig veraltet ist

Die Unterschiede in Bezug auf die Leistung sehr gering sind.

Einige Details (PL)

Wie können wir eine href lesen <= "https://bugs.mysql.com/bug.php?id=9604%20%E2%80%93%20user3399549%20Mar%209%20%2714%20at% 2021: 15" rel = "nofollow noreferrer"> hier ( Peter Gulutzan ) gibt es Unterschiede auf Sortieranlagen / Vergleich polish Buchstaben "L" (L mit Schlaganfall - html esc: &#321;) ( Kleinbuchstaben: "L" - html esc: &#322;) - haben wir folgende Annahme:

utf8_polish_ci      Ł greater than L and less than M
utf8_unicode_ci     Ł greater than L and less than M
utf8_unicode_520_ci Ł equal to L
utf8_general_ci     Ł greater than Z

In polnischer Sprache Brief Ł ist nach Brief L und vor M. Keiner dieser Codierung ist besser oder schlechter - es Ihre Bedürfnisse ab.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top