SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 23.04.2016 02:16:47

E.Wolf
Участник
Зарегистрирован: 23.04.2016
Сообщений: 10

CHAR, VARCHAR и индексы

Доброго времени суток уважаемые!

Гипотетическая ситуация.

База: MySQL/MariaDB/Percona.

Есть таблица значений, состоящая из: id и char(250) или id и char(65535). Во втором поле (char) содержатся значения смешанного типа (строки, числа, etc), по которым производится выборка, от простого WHERE char_field = 100; до более сложных, вроде BETWEEN, LIKE '%abc%' и так далее, в т.ч. множественные AND/OR.

Ориентировочное количество записей в таблице - 1 млн. (возможно увеличение до 5-10 млн.)

Для меня не до конца понятны следующие моменты:
1. Максимальная длина индекса, можно ли проиндексировать поле VARCHAR(65535) полностью?
2. Учитывается ли при расчёте максимальной длины индекса кодировка БД (таблицы)
3. Длина каждого отдельно взятого индекса будет равняться максимальной длине поля или фактической (подозреваю, что максимальной)
4. Даст ли какой-то прирост производительности смена кодировки таблиц с utf8_general_ci на какую-то однобайтовую кодировку, вроде cp1251 или koi8?

Тип таблиц - InnoDB.

Буду крайне признателен за любые комментарии по теме. Спасибо.

Неактивен

 

#2 23.04.2016 12:15:39

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: CHAR, VARCHAR и индексы

1. нет

http://dev.mysql.com/doc/refman/5.7/en/create-index.html написал:

Prefix support and lengths of prefixes (where supported) are storage engine dependent. For example, a prefix can be up to 767 bytes long for InnoDB tables or 3072 bytes if the innodb_large_prefix option is enabled. For MyISAM tables, the prefix limit is 1000 bytes. The NDB storage engine does not support prefixes

2.

там же написал:

Prefix limits are measured in bytes, whereas the prefix length in CREATE TABLE, ALTER TABLE, and CREATE INDEX statements is interpreted as number of characters for nonbinary string types (CHAR, VARCHAR, TEXT) and number of bytes for binary string types (BINARY, VARBINARY, BLOB). Take this into account when specifying a prefix length for a nonbinary string column that uses a multibyte character set.

3. http://sqlinfo.ru/forum/viewtopic.php?id=2341
4. нет

Неактивен

 

#3 23.04.2016 12:31:40

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: CHAR, VARCHAR и индексы

По пунтку 4 - заменой кодировки Вы сможете проиндексировать более длинную части колонки. UTF8 в MySQL всегда занимает 3 байта на символ.

Неактивен

 

#4 23.04.2016 12:31:41

E.Wolf
Участник
Зарегистрирован: 23.04.2016
Сообщений: 10

Re: CHAR, VARCHAR и индексы

vasya, спасибо!

Я бы хотел уточнить некоторые моменты. Как я понимаю, максимальная длина индекса в InnoDB составляет 767 байт на единицу (если опция innodb_large_prefix выключена), при этом, текст в кодировке utf8_general_ci занимает 3 байта/символ. Соответственно, мы можем максимально проиндексировать после в 255 символов?

Что будет, если мне нужно проиндексировать поля по 65000 байт, или поля заранее не известной длины, но укладывающиеся в 16Mb (например, LONGTEXT поле?).

Если максимально сократить задачу до логического конца, то звучать вопрос будет примерно так: как максимально ускорить поиск и сложную выборку (LIKE, <=>, BETWEEN и пр. условия сравнения и выборки) по полям переменной длины, содержащие смешанные значения длиной от 1 цифры/символа, до нескольких Мб текста.

Благодарю за внимание.

Неактивен

 

#5 23.04.2016 12:32:59

E.Wolf
Участник
Зарегистрирован: 23.04.2016
Сообщений: 10

Re: CHAR, VARCHAR и индексы

rgbeast, спасибо! Я как раз так и подумал... А производительности это не добавит? Логически ведь индекс тогда будет занимать 1 байт на символ, вместо 3-х в памяти и на жестком диске...

Неактивен

 

#6 23.04.2016 12:33:33

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: CHAR, VARCHAR и индексы

Вы можете максимально проиндексировать первые 767 байт от значения. Поэтому реальная длина записи не имеет значения - индекс будет фиксированной, заданной вами, длины.

Неактивен

 

#7 23.04.2016 12:41:25

E.Wolf
Участник
Зарегистрирован: 23.04.2016
Сообщений: 10

Re: CHAR, VARCHAR и индексы

rgbeast, правильно ли я понимаю, что как-то ощутимо ускорить процесс индексации подобного рода полей невозможно, просто проиндексируются первые N-символов (в зависимости от кодировки), а если значение занимает, скажем, 1Мб текста, и соответственно большая его часть выходит за пределы индекса, то? Как поведёт себя MySQL? Он начнёт сканировать все поля в поисках подходящих под условие значений, или сначала пройдёт по индексированным, а потом определит длину полей которые выходят за пределы индекса и просканирует их отдельно?

Суть в том, что 95% значений будут от 1 до 30 символов, и примерно 5% будут иметь вариативную длину.

Неактивен

 

#8 23.04.2016 12:49:48

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: CHAR, VARCHAR и индексы

Если данные занимают меньше места в памяти и на диске, то это влияет на производительность. Однако, нужно вернуться к исходной задаче. Если ищете LIKE '%слово%', то такая операция не будет использовать индекс ни при каких условиях (альтернативный подход - FULLTEXT индексы). Чтобы понять почему, возьмите телефонный справочник (аналог индекса) и найдите в нем все фамилии, содержащие '%бекер%'. Только полный перебор поможет решить такую задачу.

Для запросов типа LIKE 'ворона%' или BETWEEN 'Брянск' AND 'Новосибирск' будет вполне достаточно первой части индекса, независимо от длины записи.

Неактивен

 

#9 23.04.2016 14:47:48

E.Wolf
Участник
Зарегистрирован: 23.04.2016
Сообщений: 10

Re: CHAR, VARCHAR и индексы

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

Интересует вот что:
- добавит ли полнотекстовый индекс скорости выборки по выражениям типа WHERE LIKE '%abc%'?
- какой может возникнуть негативный эффект, в результате использования полнотекстовых индексов? База будет больше есть оперативки, диска, медленнее работать?

Заранее благодарю.

P.S. Я поискал информацию касательно полнотекстовых индексов в интернете, разумеется, перед тем как кого-то дёргать, но информация сильно разрежена и в основном рассматривается полнотекстовый поиск match/against, никто не рассматривает примеры типа WHERE LIKE '%abc%' и толк от этих индексов при таких условиях.

Отредактированно E.Wolf (23.04.2016 14:50:01)

Неактивен

 

#10 23.04.2016 15:05:53

E.Wolf
Участник
Зарегистрирован: 23.04.2016
Сообщений: 10

Re: CHAR, VARCHAR и индексы

Я тут вычитал, что match/against работают быстрее WHERE LIKE '%abc%', на полях с полнотекстовым индексом, но это не работает в таблицах InnoDB, при этом указано, что "проблема в том, что нам нужно искать по нескольким полям", в моём конкретном случае, нужно искать по одному и только одному полю (одной колонке) и исключительно в InnoDB. Подскажите пожалуйста, возможно ли что-то подобное при условии поиска по одному полю, в том смысле, даст ли это какой-то ощутимый прирост скорости при замене условия WHERE LIKE '%abc%' на WHERE MATCH(`column1`) AGAINST('*abc*' IN BOOLEAN MODE)?

Неактивен

 

#11 23.04.2016 23:51:09

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: CHAR, VARCHAR и индексы

E.Wolf, вы уже на многое ответили. Полнотекстовый индекс не используется для LIKE. Он работает только для MATCH AGAINST. В Innodb такие индексы работают начиная с MySQL 5.6.

Неактивен

 

#12 23.04.2016 23:57:32

E.Wolf
Участник
Зарегистрирован: 23.04.2016
Сообщений: 10

Re: CHAR, VARCHAR и индексы

rgbeast, спасибо большое! В Innodb такие индексы работают начиная с MySQL 5.6. - вот это вообще очень ценная информация, мне нигде не попадался на глаза сей важнейший факт. Последнее, что хотел бы уточнить, начиная с версии 5.6 эти индексы работают по одному полю, или можно выставлять на несколько полей сразу?

P.S. Очень не хватает кнопочки "спасибо" или кнопочки "Понравился ответ? Пожертвовать чирик/полтинник", или обоих кнопочек сразу big_smile

Неактивен

 

#13 24.04.2016 00:11:19

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: CHAR, VARCHAR и индексы

E.Wolf, спасибо за добрый отзыв!

Индексы FULLTEXT могут работать на несколько полей.

Неактивен

 

#14 24.04.2016 00:21:03

E.Wolf
Участник
Зарегистрирован: 23.04.2016
Сообщений: 10

Re: CHAR, VARCHAR и индексы

rgbeast, ещё раз примного благодарен!

Буквально только что нашел 3 или 4 упоминания полнотекстовый поиск работает только на MyISAM, и эта информация, как мы выяснили, уже устарела... Вот так и учимся, "пока жареный не клюнет"...

Думаю вопрос можно считать решенным (тему раскрытой), и где-нибудь жирным шрифтом написать "InnoDB теперь поддерживают полнотекстовые индексы!", хотя бы для таких ископаемых как я, которые помнят MySQL с версии 3.х а то и более ранних...

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson