Я хотел бы задать пару вопросов о порядке столбцов в составном индексе для движка InnoDB и об объяснении мощности и селективности, которые должны быть выполнены (и как это сделать), чтобы получить наилучшую производительность на представленном примере. .
- В чем разница между селективностью и кардинальностью в контексте производительности составного индекса InnoDb?
- Когда следует делать акцент на селективности и на кардинальности, если вы создаете составной индекс?
Так как InnoDB использует индекс B-Tree (B-Tree +), а сопоставленный индекс ищется, начиная с крайнего левого столбца, из которого составляется индекс.
Насколько я понимаю,имеет смысл использовать такой порядок объединения столбцов, чтобы крайний левый столбец выбрасывал наибольшую несоответствующую часть индекса из поиска и продолжал искать меньше данных для поиска, следующий столбец составного индекса должен иметь такое же свойство, чтобы всеостальные, пока поиск не сузитсяКоличество строк, потенциально совпадающее с наименьшим количеством, на котором он может сканировать для поиска точно совпадающих строк.
Короче говоря, я понимаю, что самый левый столбец должен быть наиболее грубым делением всех строк и следующих столбцов составного индекса. будет все больше и больше мелкозернистых рядов.
Это кардинальность? и если составной индекс строится таким образом, как я описал, то является ли количество элементов высоким или низким?
Как насчет селективности? коррелируется ли это с количеством элементов?
5.Как получить лучшую селективность и количество элементов для дизайна таблицы, как показано ниже?
CREATE TABLE IF NOT EXISTS `data_list` (
`one` varchar(64) NOT NULL,
`two` mediumint unsigned NOT NULL,
`three` varchar(128) NOT NULL,
`four` datetime NOT NULL,
`five` DECIMAL(5,2)
) ENGINE = InnoDB;
максимальные значения различного числа столбцовбудет:
one
макс. 10;
two
макс. 100;
three
макс. 1000;
four
макс. 36500;// 100 лет
вторая таблица для специальных соединений:
CREATE TEMPORARY TABLE IF NOT EXISTS `three_list` (
`l_three` varchar(128) PRIMARY KEY NOT NULL
) ENGINE = InnoDB;
Запросы, которые будут выдаваться:
(A) Запрос для конкретного one
, two
, three
, four
SELECT *
FROM
`data_list`
WHERE
`one` = 'abc'
AND
`two` = 1
AND
`three` = 'xyz'
AND
`four` = '2018-01-01'
;
(B) Запрос для конкретных one
, two
, three
и диапазона four
SELECT *
FROM
`data_list`
WHERE
`one` = 'abc'
AND
`two` = 1
AND
`three` = 'xyz'
AND
`four` >= '2018-01-01'
AND
`four` < '2019-01-01'
ORDER BY
`two`,
`three`,
`four`
;
(C) Запрос для конкретного one
, two
и любого three
в пределах диапазона four
SELECT *
FROM
`data_list`
WHERE
`one` = 'abc'
AND
`two` = 1
AND
`four` >= '2018-01-01'
AND
`four` < '2019-01-01'
ORDER BY
`two`,
`three`,
`four`
;
(D) Запрос с JOIN
для конкретного one
иtwo
, three
в списке three_list
и four
в пределах диапазона
SELECT *
FROM
`data_list`
INNER JOIN
`three_list`
ON
`three` = `l_three`
WHERE
`one` = 'abc'
AND
`two` = 1
AND
`four` >= '2018-01-01'
AND
`four` < '2019-01-01'
ORDER BY
`two`,
`three`,
`four`
;
Возможно, вся конструкция таблицы имеет недостатки с самого начала (т. Е. Из-за отсутствия PK id
с auto_increment для data_list
). Этот вопрос касается кардинальности и избирательности для лучшей производительности составного индекса, однако приветствуется альтернативный дизайн таблицы в случае, если нет хорошего выбора порядка столбцов для запросов, как указано выше.
Самая важная производительность для менядля операторов SELECT. Вставки будут редкими (один раз в день), а ОБНОВЛЕНИЕ, УДАЛЕНИЕ не понадобятся.
Строки должны быть уникальными в data_list
Я имею в виду комбинацию one
, two
,three
, four
значения столбцов.