我想问几个有关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`,`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`,`four`
;
也许整个表设计从一开始就存在缺陷(即由于没有id
的PK data_list
和auto_increment)。这个问题是关于综合索引的最佳性能的基数和选择性,但是,如果上面没有用于查询的好的列顺序选择,那么也欢迎使用替代表设计。
对我来说,最重要的性能是SELECT语句。 INSERT将很少见(每天一次),并且不需要UPDATE,DELETE。
行在data_list
中必须是唯一的,我的意思是one
,two
,three
,four
列值的组合。