创建索引的几点建议,列的离散度,前缀索引

简介: 创建索引

1.列的离散度 建立索引,要使用离散度(选择度)更高的字段。

2.前缀索引

当字段值比较长的时候,建立索引会消耗很多的空间,搜索起来也会很慢。我们可以通过截取字段的前面一部分内容建立索引,这个就叫前缀索引。

建立前缀索引

create table shop(address varchar(120) not null); alter table shop add key(address(12));   // 截取12个字符作为前缀索引是最优的吗?

问题是,截取多少呢?截取得多了,达不到节省索引存储空间的目的,截取得少了,重复内容太多,字段的散列度(选择性)会降低。怎么计算不同的长度的选择性呢?

先看一下字段在全部数据中的选择度计算公式:

select count(distinct address) / count() from shop;select count(distinct left(address, n)) / count() as subn from shop;

count(distinct left(address,n)) / count(*) 的结果是会随着 n 的变大而变大。举个例子,现在有两个address(东大街长兴小区,东大街福乐小区),那么 distinct(address,2) < distinct(address,3)==>所以,截取的长度越长就会越接近字段在全部数据中的选择度==>所以,我们要权衡索引大小和查询速度。

举个例子,通过不同长度去计算,与全表的选择性对比:

SELECT  COUNT(DISTINCT(address))/COUNT() sub,            -- 字段在全部数据中的选择度COUNT(DISTINCT(LEFT(address,5)))/COUNT() sub5,   -- 截取前5个字符的选择度COUNT(DISTINCT(LEFT(address,7)))/COUNT() sub7,  COUNT(DISTINCT(LEFT(address,9)))/COUNT() sub9,COUNT(DISTINCT(LEFT(address,10)))/COUNT() sub10,  -- 截取前10个字符的选择度COUNT(DISTINCT(LEFT(address,11)))/COUNT() sub11,COUNT(DISTINCT(LEFT(address,12)))/COUNT() sub12,COUNT(DISTINCT(LEFT(address,13)))/COUNT() sub13,COUNT(DISTINCT(LEFT(address,15)))/COUNT(*) sub15 FROM shop;

sub sub5 sub7 sub9 sub10 sub11 sub12 sub13 sub15
0.9993 0.0225 0.4663 0.8618 0.9734 0.9914 0.9943 0.9943 0.9958

可以看到在截取 11 个字段时 sub11(0.9993) 就已经很接近字段在全部数据中的选择度 sub(0.9958)了,而且长度也相较后面更短一些, 综合考虑比较合适。

ALTER TABLE shop ADD KEY (address(11));

3.几点具体的建议索引的个数不要过多(浪费空间,更新变慢)在用于 where 判断 order 排序和 join 的(on)字段上创建索引区分度低的字段,例如性别,不要建索引(离散度太低,导致扫描行数过多)更新频繁的值,不要作为主键或者索引(页分裂)不建议用无序的值作为索引,例如身份证、UUID(在索引比较时需要转为ASCII,并且插入时可能造成页分裂)若在多个字段都要创建索引的情况下,联合索引优于单值索引联合索引把散列性高(区分度高)的值放在前面其实,用不用索引,最终都是优化器说了算。优化器是基于什么的优化器?基于cost开销(CostBaseOptimizer),它不是基于规则(Rule-BasedOptimizer),也不是基于语义。怎么样开销小就怎么来。 另外,SQL语句是否使用索引,跟数据库版本、数据量、数据选择度都有关系。

相关文章
|
6月前
|
索引
15. 索引是越多越好嘛? 什么样的字段需要建索引, 什么样的字段不需要 ?
是否越多索引越好?并非如此。应根据需求建索引:主键自动索引,频繁查询、关联查询、排序、查找及统计分组字段建议建索引。但表记录少,频繁增删改操作,频繁更新的字段,以及使用频率不高的查询条件则不需要建索引。
115 0
|
27天前
|
数据库 索引
联合索引和单独列索引哪个更好
【10月更文挑战第15天】联合索引和单独列索引哪个更好
43 2
|
27天前
|
数据库 索引
联合索引和单独列有什么区别
【10月更文挑战第15天】联合索引和单独列有什么区别
42 2
|
索引
索引是越多越好嘛? 什么样的字段需要建索引, 什么样的字段不需要 ?
索引是越多越好嘛? 什么样的字段需要建索引, 什么样的字段不需要 ?
130 0
|
存储 SQL 缓存
B+树索引使用(9)分组、回表、覆盖索引(二十一)
B+树索引使用(9)分组、回表、覆盖索引(二十一)
|
关系型数据库 MySQL 索引
B+树索引使用(7)匹配列前缀,匹配值范围(十九)
B+树索引使用(7)匹配列前缀,匹配值范围(十九)
|
关系型数据库 MySQL 索引
二十四、复合索引前导列
二十四、复合索引前导列
266 0
|
SQL 关系型数据库 数据库
PostgreSQL 设计优化case - 大宽表任意字段组合查询索引如何选择(btree, gin, rum) - (含单个索引列数超过32列的方法)
标签 PostgreSQL , adhoc查询 , 大宽表 , 任意字段组合查询 , 索引 , btree , gin , rum 背景 大宽表,任意字段组合查询,透视。是实时分析系统中的常见需求: 1、实时写入。
2675 0