составной индекс в mysql, если один столбец очень часто - PullRequest
0 голосов
/ 07 января 2020

У меня есть таблица, которая содержит данные для нескольких арендаторов.

CREATE TABLE `accountPost` (
 `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
 `tenantId` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '',
 `accountId` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
 `scheduledTime` BIGINT(19),
 ......more columns
 PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=781625 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

Здесь scheduleTime - это отметка времени. tenantId будет общим для множества строк accountPost.

Теперь у меня есть запрос типа

select * from accountPost
    where scheduledTime > t1
      and scheduledTime < t2
      and tenantId = "x";

Для этого запроса я хочу создать составной индекс.

1. ALTER TABLE `accountPost` ADD INDEX `idx1` (`scheduledTime`, `tenantId`);
2. ALTER TABLE `accountPost` ADD INDEX `idx1` (`tenantId`, `scheduledTime`);

Какой из этих двух я должен использовать, чтобы получить оптимальную производительность для вставки, а также чтения и почему? Нужно ли добавлять более частый столбец первым в составном индексе?

1 Ответ

2 голосов
/ 07 января 2020

Мощность отдельных компонентов составного индекса не имеет значения.

Важно поставить = столбцы перед < (et c) столбцами. Так что это обязательно лучший порядок:

INDEX(`tenantId`, `scheduledTime`)

(Между тем порядок пунктов в WHERE не важен.)

Что касается чтения против записи ... The SELECT польза от хорошего индекса значительно перевешивает незначительные накладные расходы на запись (вставка / обновление / удаление). Добавьте все индексы, необходимые для чтения; бросить любые избыточные или никогда не используемые индексы. Тогда не беспокойтесь.

Совет по сравнению дат (или datetime): остерегайтесь BETWEEN или, в вашем примере, < и > - они либо включают, либо исключают оба конечные точки. Мне нравится следующий шаблон:

WHERE dt >= '2019-12-27'
  AND dt  < '2019-12-27' + INTERVAL 7 DAY

Совет схем: подумайте об использовании меньших типов данных. 255 удобен, но имеет некоторые незначительные проблемы с производительностью. BIGINT (8 байт) почти всегда больше, чем необходимо. Размер имеет значение для дискового пространства и кэширования.

Где вы взяли BIGDECIMAL ??

Подробнее: http://mysql.rjweb.org/doc.php/index_cookbook_mysql

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...