Является ли varchar 2 более эффективным, чем varchar 255? - PullRequest
10 голосов
/ 13 января 2010

Я использую Django и настраиваю свой CharField ( max_length = 255 ), хотя я собираюсь использовать только около 5 символов. Это менее эффективно? Я читал, что с varchar это не имеет значения, но потом прочитал, что это сэкономит место на жестком диске, чтобы указать только то, что вам нужно.

Ответы [ 5 ]

12 голосов
/ 13 января 2010

Как правило, varchar (255) требует столько же памяти, сколько varchar (1). В каждом случае таблица хранит что-то вроде указателя на таблицу строк и длину. Например. Смещение 4 байта + размер 1 байта = 5 байтов фиксировано на строку, только для служебных данных.

Фактическое содержимое, конечно, находится в таблице строк, которая равна длине строки вашего магазина в ней. Поэтому, если вы сохраните 5-буквенное имя в поле varchar (255), оно будет использовать, скажем, только 5 служебных байтов + 5 байтов содержимого = 10 байтов.

Использование поля varchar (10) будет использовать точно такое же количество, но будет усекать только строки длиной более 10 байтов.


Конечно, конкретные числа зависят от реализации механизма хранения.

4 голосов
/ 13 января 2010

varchar не займет больше места, чем строка, которую вы храните в нем, кроме служебных данных для хранения длины строки :

+------------------------------------------+---------------------------------+
| Value      | CHAR(4)    Storage Required | VARCHAR(4)   Storage Required   |  
+------------+-----------------------------+---------------------------------+
| ''         | '    '     4 bytes          | ''           1 byte             |
| 'ab'       | 'ab  '     4 bytes          | 'ab'         3 bytes            | 
| 'abcd'     | 'abcd'     4 bytes          | 'abcd'       5 bytes            |
| 'abcdefgh' | 'abcd'     4 bytes          | 'abcd'       5 bytes            |
+------------+-----------------------------+---------------------------------+

Однако, если вам действительно требуется только 5 символов, рассмотрите возможность использования char (5), если в таблице нет других столбцов переменной ширины (т. Е. Varchars, text или blob). Тогда у вас будет фиксированная длина записи, которая имеет некоторые преимущества в производительности :

Для таблиц MyISAM, которые меняются часто вам следует избегать все столбцы переменной длины (VARCHAR, BLOB и ТЕКСТ). Таблица использует динамический формат строки, если он включает даже один столбец переменной длины. Увидеть Глава 13, Двигатели хранения.

2 голосов
/ 29 января 2010

Одно предостережение относительно использования char вместо varchar в том, что набор символов влияет на пространство, которое должно быть выделено. Например, если для этого столбца используется набор символов utf8, возможно, для хранения одного символа потребуется 3 байта.

Поскольку столбец char приводит к выделению фиксированного размера независимо от того, что хранится, база данных должна соответствовать наихудшему случаю. Таким образом, MySQL всегда должен выделять 15 байтов на строку для этого столбца char (5), даже если вы на самом деле храните только 5 однобайтовых символов в каждой строке.

varchar использует только то, что необходимо для каждой строки, так как он хранится, поэтому те же самые 5 однобайтовых символов занимают всего 6 или 7 байтов. Один или два дополнительных байта предназначены для отслеживания фактической длины. Для varchar шириной до 255 в однобайтовом наборе символов MySQL должен выделить только 1 байт для хранения фактической ширины. Varchar шириной от 256 до 65 535 требуется 2 байта для хранения длины, принимая однобайтовый набор символов.

Поскольку для utf8 varchar (255) может потребоваться 255 * 3 байта памяти, MySQL должен выделить 2 байта для хранения длины. Большая часть этой информации описана в документации по MySQL здесь .

Хотя вы можете объявить ширину 65 535, максимальный эффективный размер в байтах составляет 65 532. Однако, в зависимости от набора символов и символов, которые вы храните, вы можете хранить не более, чем много многобайтовых символов.

Однако, как указывает Пол, вы все равно можете использовать символ, если это позволит фиксировать ширину всего ряда. Помимо прочего, некоторые поиски могут быть быстрее (например, пропустить первые 1000 строк) из-за фиксированного смещения.

Существуют также проблемы с производительностью, которые необходимо учитывать при обновлении столбца. Если у вас есть char (5) и вы начинаете с 1 символа, а затем обновляете значение до 5 символов, строка может быть обновлена ​​на месте. При использовании varchar, в зависимости от реализации механизма хранения, может потребоваться перезапись всей строки в новом месте.

Наконец, если MySQL необходимо создать временную таблицу в памяти для сортировки набора результатов из вашей постоянной таблицы, он использует записи фиксированной длины. Таким образом, он выделяет намного больше места в памяти для этих негабаритных столбцов varchar, чем вы могли подумать. Это описано в документации по MySQL для таблиц подсистемы хранения памяти. Я считаю, что MySQL также делает это для дисковых сортировок.

1 голос
/ 13 января 2010

Место на жестком диске дешево, но место в кеше процессора дорого. Вы можете разместить больше полей меньшего размера, чем полей большего размера.

0 голосов
/ 13 января 2010

Вместо ненужного использования большого пространства, используйте пространство, которое не только даст вам больше места для хранения, но также и высокую скорость выполнения, так как не нужно было читать все символы. Если вы выделите varchar (255) и добавите текст «abc», он будет читать символы «a», «b», «c» и другие как пробел.

Итак, всегда используйте требуемое пространство вместо того, чтобы сохранять максимальное пространство.

...