VARCHAR против производительности TEXT, когда данные помещаются в строку - PullRequest
7 голосов
/ 23 сентября 2019
mysql> desc temp1;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| value | varchar(255) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+

mysql> desc temp2;
+-------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------+------+-----+---------+-------+
| value | text | YES  |     | NULL    |       |
+-------+------+------+-----+---------+-------+

255 - символы 'a' в каждой строке (в обеих таблицах)

mysql> select * from temp1 limit 1;
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| value                                                                                                                                                                                                                                                           |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

mysql> select * from temp2 limit 1;
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| value                                                                                                                                                                                                                                                           |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Таблица запросов 1:

select count(*) from temp1 where value like '%a';

Таблица запросов 2:

select count(*) from temp2 where value like '%a';

Статистика:

No of records---temp1(varchar)---temp2(text)


2097152---------6.08(sec)--------6.91(sec)          
4194304---------12.42(sec)-------13.66(sec)
8388608---------25.08(sec)-------28.03(sec)
16777216--------52.82(sec)-------56.88(sec)
33554432--------1(min)50.17(sec)-1(min)59.36(sec)

Мой вопрос: КакМожно ли объяснить разницу в скорости выполнения?

Содержимое строк в обеих таблицах одинаковое.

Как я понял, столбцы VarChar и Text держат содержимое offPage только тогда, когда оно превышает размер строки,Таким образом, содержимое обеих таблиц будет встроенными данными для моего page size(16kb).Тогда какова была причина этой разницы во времени выполнения запроса.

Примечание. Оба столбца таблицы не проиндексированы

Row Format - DYNAMIC

Collation - UTF8mb3

Character set - utf8_general_ci

Storage engine -  innodb

Mysql - 5.7

Ссылочная ссылка: https://stackoverflow.com/a/48301727/5431418

Обновление: Тот же поток, что я попробовал, используя 5000 символов ('a') в обеих таблицах, разница результатов высока.

2097152---------1(min)53.63(sec)--------2(min)4.66(sec)    

Обновление 2: Тот же поток, который я пытался выполнить с двумя символами ('a') в обеих таблицах, однако разница в производительности сохраняется.

Ответы [ 2 ]

1 голос
/ 23 сентября 2019

давайте использовать некоторые инструменты

Поскольку первоначальная догадка (см. Ниже) была пропущена , попробуйте выполнить запрос через MySQL Workbench , чтобы собрать Статистика производительности запросов .

начальная догадка (без результата)

Всего лишь мысль:

  • TEXT размер столбца на диске 2 + N байтгде N - длина строки
  • VARCHAR занимает 1 + N байтов (для N ≤ 255) или 2 + N байтов (для 256 ≤ N ≤ 65535)

Попробуйте увеличить размер текста в столбце выше 256 символов и повторите тесты.Потенциально они будут работать с производительностью, более точно подобранной.

Обратите также внимание на то, что публикуемые вами различия выражаются в микросекундах на запись, поэтому может быть много мешающих событий ОС или очень простой путь кода if (TEXT) {do some additional IO or housekeeping}в источнике.

0 голосов
/ 30 сентября 2019

Тип TEXT всегда будет медленнее, чем VARCHAR, потому что эти типы имеют разные способы хранения.Поле VARCHAR хранится в таблице со всеми столбцами, но TEXT хранится по-разному.Каждое значение TEXT является отдельным объектом.Это означает, что если вы хотите что-то сделать со значением TEXT, MySQL сделает дополнительные операции для получения этого объекта.

Цитата из официальной документации :

Каждое значение BLOB или TEXT внутренне представлено отдельно выделенным объектом.Это отличается от всех других типов данных, для которых хранилище выделяется один раз на столбец при открытии таблицы.

...