Co jest szybsze: char (1) Czy tinyint (1)? Dlaczego?

MOJA PLATFORMA:

PHP & mySQL

MOJA SYTUACJA:

Natknąłem się na sytuację, w której muszę przechowywać wartość do wyboru użytkownika w jednej z moich kolumn tabeli. Teraz moje opcje to:

  1. albo zadeklarować kolumnę jako char(1) i zapisać wartość jako " y " lub " n "
  2. lub zadeklarować kolumnę jako tinyint(1) i zapisać wartość jako 1 lub 0
  3. tak zadeklarowana kolumna może być również indeksowana do użytku w podanie.

MOJE PYTANIA:

Więc chciałem wiedzieć, który z powyższych dwóch typów:

  1. Prowadzi do szybszej szybkości zapytań, gdy ta kolumna jest dostępna(dla uproszczenia, zostawmy mieszanie innych zapytań lub uzyskiwanie dostępu do innych kolumn, proszę).

  2. Czy najbardziej efektywny sposób przechowywania i uzyskiwania dostępu do danych i dlaczego?

  3. Jak zmienia się szybkość dostępu, jeśli kolumny są indeksowane, a jeśli nie?

Rozumiem, że ponieważ char(1) i tinyint(1) zajmują tylko 1 bajtową przestrzeń, przestrzeń pamięci nie będzie problemem w tym przypadku. Wtedy pozostaje prędkość dostępu. Z tego co wiem, indeksowanie numeryczne jest szybsze i wydajniejsze niż cokolwiek innego. Ale sprawa tutaj jest trudna do rozstrzygnięcia. Na pewno chciałbym usłyszeć Twoje doświadczenia na ten temat.

Z góry dziękuję.

Author: IJas, 2010-01-07

8 answers

Myślę, że powinieneś utworzyć kolumnę z ENUM('n','y'). Mysql przechowuje ten typ w optymalny sposób. To również pomoże Ci przechowywać tylko dozwolone wartości w polu.

Możesz również uczynić go bardziej przyjaznym dla człowieka ENUM('no','yes') bez wpływu na wydajność. Ponieważ ciągi 'no' i 'yes' są przechowywane tylko raz dla ENUM definicji. Mysql przechowuje tylko indeks wartości w wierszu.

Zwróć również uwagę na sortowanie według ENUM kolumny:

Wartości ENUM są sortowane według kolejności w których członkowie wyliczający byli wymienieni w kolumnie Specyfikacja. (Innymi słowy, wartości ENUM są sortowane według ich numerów indeksowych.) Na przykład,' a 'sortuje przed' b ' Dla ENUM ('a',' b'), ale' b 'sortuje przed' a ' dla ENUM ('b','a').

 30
Author: Ivan Nevostruev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-07 22:06:22
                       Rate insert tinyint(1) insert char(1) insert enum('y', 'n')
insert tinyint(1)     207/s                --            -1%                  -20%
insert char(1)        210/s                1%             --                  -19%
insert enum('y', 'n') 259/s               25%            23%                    --
                       Rate insert char(1) insert tinyint(1) insert enum('y', 'n')
insert char(1)        221/s             --               -1%                  -13%
insert tinyint(1)     222/s             1%                --                  -13%
insert enum('y', 'n') 254/s            15%               14%                    --
                       Rate insert tinyint(1) insert char(1) insert enum('y', 'n')
insert tinyint(1)     234/s                --            -3%                   -5%
insert char(1)        242/s                3%             --                   -2%
insert enum('y', 'n') 248/s                6%             2%                    --
                       Rate insert enum('y', 'n') insert tinyint(1) insert char(1)
insert enum('y', 'n') 189/s                    --               -6%           -19%
insert tinyint(1)     201/s                    7%                --           -14%
insert char(1)        234/s                   24%               16%             --
                       Rate insert char(1) insert enum('y', 'n') insert tinyint(1)
insert char(1)        204/s             --                   -4%               -8%
insert enum('y', 'n') 213/s             4%                    --               -4%
insert tinyint(1)     222/s             9%                    4%                --

Wydaje się, że w większości przypadków enum('y', 'n') jest szybszy do wstawienia.

                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        188/s             --               -7%                   -8%
select tinyint(1)     203/s             8%                --                   -1%
select enum('y', 'n') 204/s             9%                1%                    --
                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        178/s             --              -25%                  -27%
select tinyint(1)     236/s            33%                --                   -3%
select enum('y', 'n') 244/s            37%                3%                    --
                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        183/s             --              -16%                  -21%
select tinyint(1)     219/s            20%                --                   -6%
select enum('y', 'n') 233/s            27%                6%                    --
                       Rate select tinyint(1) select char(1) select enum('y', 'n')
select tinyint(1)     217/s                --            -1%                   -4%
select char(1)        221/s                1%             --                   -2%
select enum('y', 'n') 226/s                4%             2%                    --
                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        179/s             --              -14%                  -20%
select tinyint(1)     208/s            17%                --                   -7%
select enum('y', 'n') 224/s            25%                7%                    --

Wybór również wydaje się być enum. Kod można znaleźć tutaj

 36
Author: Glen Solsberry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-08 14:01:55

Używanie tinyint jest bardziej standardową praktyką i pozwoli Ci łatwiej sprawdzić wartość pola.

// Using tinyint 0 and 1, you can do this:
if($row['admin']) {
    // user is admin
}

// Using char y and n, you will have to do this:
if($row['admin'] == 'y') {
    // user is admin
}

Nie jestem ekspertem w wewnętrznym działaniu MySQL, ale intuicyjnie wydaje mi się, że pobieranie i sortowanie pól liczb całkowitych jest szybsze niż pól znaków (po prostu mam wrażenie, że 'A' > 'z' to więcej pracy niż 0 > 1), i wydaje się być bardziej znane z perspektywy obliczeniowej, w której 0s i 1s są standardowymi flagami włączania/wyłączania. Więc magazyn dla liczb całkowitych wydaje się być lepiej, jest przyjemniejszy i łatwiejszy w użyciu w logice kodu. 0/1 jest dla mnie oczywistym zwycięzcą.

Można również zauważyć, że w pewnym stopniu jest to oficjalne stanowisko MySQL, a także z ich dokumentacji :

BOOL, BOOLEAN: te rodzaje są synonimami dla TINYINT (1) Wartość zero to uważany za fałszywy. Wartości niezerowe to / align = "left" /

Jeśli MySQL idzie tak daleko, aby zrównać TINYINT(1) z BOOLEAN, wydaje się, że jest to droga do zrobienia.

 10
Author: Matchu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-07 20:48:21

Aby mieć pewność, powinieneś to porównać. Albo wiedz, że prawdopodobnie nie będzie to miało większego znaczenia w szerszym widoku całego projektu.

Kolumny Char mają kodowanie i kolacje, a porównywanie ich może wiązać się z niepotrzebnymi przełącznikami między kodowaniami, więc domyślam się, że int będzie szybszy. Z tego samego powodu uważam, że aktualizacja indeksu w kolumnie int jest również szybsza. Ale znowu, to nie będzie miało większego znaczenia.

CHAR może zająć więcej niż jeden bajt, w zależności od wybrane opcje zestawu znaków i tabeli. Niektóre znaki mogą kodować trzy bajty, więc MySQL czasami rezerwuje tę przestrzeń, nawet jeśli używasz tylko y i n.

 4
Author: Jan Fabry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-07 20:56:54

Oboje będą tak blisko, że to nie ma znaczenia. Jeśli czujesz, że musisz zadać to pytanie na tak, jesteś nadmiernej optymalizacji. Użyj tego, który ma najbardziej logiczny sens.

 2
Author: Dave Markle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-07 20:48:07

Jeśli podczas tworzenia tabeli w MySQL podasz typy BOOL LUB BOOLEAN jako typ kolumny, utworzy on Typ kolumny jako TINYINT(1). Prawdopodobnie jest to szybszy z tych dwóch.

Dokumentacja

Także:

Zamierzamy zaimplementować pełny boolean obsługa typu, zgodnie z standard SQL, w przyszłości MySQL uwolnij.

 1
Author: Powerlord,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-07 20:50:16

Chociaż moim przeczuciem jest to, że indeks na TINYINT byłby szybszy niż indeks na CHAR(1) ze względu na fakt, że nie ma narzutu obsługi łańcuchów (kolacji, spacji itp.), nie mam żadnych faktów, które by to potwierdziły. Domyślam się, że nie ma znaczącej różnicy w wydajności, o którą warto się martwić.

Jednakże, ponieważ używasz PHP, przechowywanie jako TINYINT ma o wiele więcej sensu. Użycie wartości 1/0 jest równoważne użyciu true i false, nawet jeśli są zwracane jako ciągi do PHP i mogą być traktowane jako takie. Możesz po prostu wykonać if ($record['field']) ze swoimi wynikami jako sprawdzanie logiczne, zamiast konwertować między 'y' i ' n ' cały czas.

 1
Author: zombat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-07 20:50:53
 TINYINT    1 Byte
CHAR(M)     M Bytes, 0 <= M <= 255
Czy jest jakaś różnica?
 0
Author: streetparade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-07 20:54:10