Чи є різниця в продуктивності MySQL між розмірами varchar? Наприклад, varchar(25)
і varchar(64000)
. Якщо ні, чи є причина, щоб не оголосити всі варшари з максимальним розміром лише для того, щоб у вас не було місця?
Чи є різниця в продуктивності MySQL між розмірами varchar? Наприклад, varchar(25)
і varchar(64000)
. Якщо ні, чи є причина, щоб не оголосити всі варшари з максимальним розміром лише для того, щоб у вас не було місця?
Відповіді:
Ви повинні усвідомити компроміси використання CHAR проти VARCHAR
З полями CHAR те, що ви виділяєте, саме те, що ви отримуєте. Наприклад, CHAR (15) виділяє і зберігає 15 байт, незалежно від того, як символи ви розміщуєте в полі. Маніпулювання рядками просте і просте, оскільки розмір поля даних повністю передбачуваний.
З полями VARCHAR ви отримуєте зовсім іншу історію. Наприклад, VARCHAR (15) насправді динамічно виділяє до 16 байт, до 15 для даних і, щонайменше, 1 додатковий байт для збереження довжини даних. Якщо у вас є рядок "привіт", який займе 6 байтів, а не 5. Маніпуляція з рядками завжди повинна виконувати певну форму перевірки довжини у всіх випадках.
Компроміс є більш очевидним, коли ви виконуєте дві речі:
1. Зберігання мільйонів чи мільярдів рядків
2. Індексація стовпців, що є або CHAR або VARCHAR
Очевидно, що VARCHAR має перевагу, оскільки дані змінної довжини створюють менші рядки і, таким чином, менші фізичні файли.
Оскільки поля CHAR потребують меншої маніпуляції з рядками через фіксовану ширину поля, пошук індексів щодо поля CHAR в середньому на 20% швидший, ніж для полів VARCHAR. Це не будь-яка здогадка з мого боку. Книга Дизайн та настройка баз даних MySQL виконала щось чудове на таблиці MyISAM, щоб довести це. Приклад у книзі зробив щось подібне:
ALTER TABLE tblname ROW_FORMAT=FIXED;
Ця директива змушує VARCHAR поводитися як CHAR. Я зробив це на своїй попередній роботі ще в 2007 році і взяв таблицю на 300 ГБ і збільшив пошукові показники на 20%, не змінюючи нічого іншого. Це працювало як опубліковано. Однак вона створила таблицю майже вдвічі більше, але це просто повертається до компромісу №1.
Ви можете проаналізувати дані, що зберігаються, щоб побачити, що рекомендує MySQL для визначення стовпців. Просто запустіть наступне проти будь-якої таблиці:
SELECT * FROM tblname PROCEDURE ANALYSE();
Це дозволить пройти всю таблицю та рекомендувати визначення стовпців для кожного стовпця на основі даних, які він містить, мінімальних значень поля, максимальних значень поля тощо. Іноді просто потрібно використовувати здоровий глузд при плануванні CHAR vs VARCHAR. Ось хороший приклад:
Якщо ви зберігаєте IP-адреси, маска для такого стовпця має максимум 15 символів (xxx.xxx.xxx.xxx). Я б стрибнув прямо в CHAR (15) з серцебиттям, тому що довжина IP-адрес не зміниться настільки сильно, а додаткова складність маніпуляцій з рядками контролюється додатковим байтом. Ви все ще можете зробити ПРОЦЕДУРНИЙ АНАЛІЗ () проти такого стовпця. Може навіть рекомендувати VARCHAR. У цьому випадку мої гроші все одно будуть знаходитися на CHAR за VARCHAR.
Проблеми CHAR проти VARCHAR можна вирішити лише за допомогою належного планування. З великою силою приходить велика відповідальність (кліше, але правда)
Відповідь на це насправді досить складна. Коротка версія: різниця є .
Під час створення тимчасових таблиць для фільтрації результатів (наприклад, GROUP BY
заяви) буде розподілена повна довжина.
Протокол проводів (відправлення рядків клієнту), швидше за все, виділяє більшу довжину.
Двигун зберігання може / може не використовувати належну варшар.
Тому що (2) Я визнаю, що провідний протокол - це не те, що мені тісно знайоме, але загальна порада тут - спробувати застосувати хоча б мінімальні зусилля, щоб відгадати довжину.
Більшість відповідей у цій темі мають 5 років, написані перед InnoDB та utf8 були за замовчуванням. Отже, дозвольте почати спочатку ...
Коли запиту потрібна внутрішня тимчасова таблиця, він намагається використовувати MEMORY
таблицю. Але MEMORY не можна використовувати, якщо
TEXT
/ BLOB
стовпці, що витягуються, навіть TINYTEXT
.VARCHAR
більша за якусь суму, ймовірно, 512 в поточній версії.Також зауважте, що VARCHARs
перетворюються на CHARs
. Отже, VARCHAR(255)
з CHARACTER SET utf8
розширенням до 765 байт, незалежно від того, що знаходиться в стовпці. Потім це може бути спровоковано:
MEMORY
таблиця стає більшою за будь-яку max_heap_table_size
або tmp_table_size
, вона буде перетворена на MyISAM і, можливо, переллється на диск.Отже, VARCHAR(25)
швидше залишиться MEMORY
, отже, швидше. (255)
не так добре, а (64000)
погано.
(В майбутньому, ймовірно, будуть тимчасові таблиці InnoDB
, і частина цієї відповіді потребуватиме перегляду.)
Стовпець varchar такого розміру робить запити на всій таблиці більш імовірними для використання тимчасових таблиць. Відповідно до книги MySQL високої продуктивності. Коли оптимізатор намагається зрозуміти, чи може він виконувати цей запит у пам’яті чи йому потрібна тимчасова таблиця, він дивиться на розмір рядка на основі визначення таблиці, тобто для швидкості він не намагається побачити, скільки 64К символів ви фактично використовуєте. Ось чому письменники рекомендують не розтягувати цей спосіб визначення за межами реальних можливих значень, які йдуть у стовпці. Очевидно, що якщо ви налаштували більше запитів на тимчасові таблиці (навіть якщо фактичний розмір даних міг би вміститися в оперативній пам’яті), ви зараз зазнали штрафних санкцій за введення-виведення, яких ви могли уникнути.
Я розумію, що менші поля можуть бути включені в індекс безпосередньо, тоді як довші - не можуть. У зв'язку з цим обмеженням, якщо ви хочете, щоб рядки були індексуючими, я б сказав, щоб вони були коротшими. В іншому випадку, ні, будучи тим, як вони обидва варчара, тоді операції, такі як сортування чи порівняння, діятимуть за той самий час, будь то поля 25 чи MAX.
переконайтеся, що вам не вистачить місця
Ця фраза означає, що ви ставите питання, оскільки ви не впевнені в даних, які ви будете зберігати в базі даних. Якщо це правда, ви зможете дізнатися, як тільки зможете, тому що вам це знадобиться для планування потужностей. Якщо, можливо, ви отримуєте елементи даних із 7000 символами, наприклад, вам потрібно знати, оскільки це може мати наслідки для продуктивності для будь-якої СУБД.
При цьому я вважаю за краще розмір стовпців, пов'язаних із очікуваним вмістом. Наприклад, телефонний номер навряд чи буде довший 50 символів, навіть якщо ви включаєте код країни та розширення. Аналогічно, поштовий індекс або поштовий індекс, швидше за все, матиме 20 символів або менше.