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

简介: 创建索引

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天前
|
关系型数据库 MySQL 数据库
MYSQL索引的分类与创建语法详解
理解并合理应用这些索引类型,能够有效提高MySQL数据库的性能和查询效率。每种索引类型都有其特定的优势,适当地使用它们可以为数据库操作带来显著的性能提升。
23 3
|
3月前
|
SQL 关系型数据库 MySQL
MySQL数据库——索引(6)-索引使用(覆盖索引与回表查询,前缀索引,单列索引与联合索引 )、索引设计原则、索引总结
MySQL数据库——索引(6)-索引使用(覆盖索引与回表查询,前缀索引,单列索引与联合索引 )、索引设计原则、索引总结
71 1
|
4月前
|
存储 关系型数据库 MySQL
MySQL索引简介(包含索引优化,索引失效,最左前缀简洁版)
MySQL索引简介(包含索引优化,索引失效,最左前缀简洁版)
64 0
|
SQL 存储 缓存
索引不是越多越好,理解索引结构原理,才有助于我们建立合适的索引!
MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等。为了避免混乱,本文将只关注于BTree索引,因为这是平常使用MySQL时主要打交道的索引。
634 0
|
存储 SQL 缓存
B+树索引使用(9)分组、回表、覆盖索引(二十一)
B+树索引使用(9)分组、回表、覆盖索引(二十一)
|
索引
索引分类、创建索引、删除索引
索引分类、创建索引、删除索引
135 0
索引分类、创建索引、删除索引
|
SQL 关系型数据库 数据库
PostgreSQL 设计优化case - 大宽表任意字段组合查询索引如何选择(btree, gin, rum) - (含单个索引列数超过32列的方法)
标签 PostgreSQL , adhoc查询 , 大宽表 , 任意字段组合查询 , 索引 , btree , gin , rum 背景 大宽表,任意字段组合查询,透视。是实时分析系统中的常见需求: 1、实时写入。
2642 0
|
存储 索引 Go
对聚集表查询的时候,未显式指定排序列的时候,默认查询结果的顺序一定是按照聚集索引顺序排序的吗
原文:对聚集表查询的时候,未显式指定排序列的时候,默认查询结果的顺序一定是按照聚集索引顺序排序的吗 本文之外可参考另外一篇文章作为补充:http://www.cnblogs.com/wy123/p/6189100.
898 0