上个帖子写了TuneTable的执行, 提到了SQL优化器使用的那些统计数据, 这里逐一的介绍一下这些统计项。了解它们看懂和分析SQL执行计划的基础。 如果您不需要做单个查询的优化工作,可以调过这部分内容。
表的统计项
- Extent Size: 表的大小,也就是记录数。在执行多表关联(JOIN)的查询时,SQL优化器会根据Extent Size值,从数据量最小的表来开始执行查询。
您还需要了解:表创建的时候Extent Size会获得一个初始值,而之后的插入修改数据并不自动修改这个值。而只有执行TuneTable才会修改这个。 这也就是为什么没有执行过TuneTable的数据库SQL性能好不了的原因。下图中的Patient表,可以看出有1,000,000记录
字段的统计项
请看下面的图
- 选择性(Selectivity)
选择性取值可以是1或者一个百分数。取值为1说明这是个unique的字段,比如上图的ID, PatientNumber。 %表示的值,取值越高说明唯一性越低。比如上图中的Name的选择性是1.2987%,说明不是唯一值,有重复的姓名,但比例不高。 相反,Sex的选择性是50%, 说明只有两个取值。
- 离散值选择性Outlier Selectivity),
始用于Caché2014.1
离散值又称为异常值(outlier)是指一组测定值中与平均值的偏差超过两倍标准差的测定值,与平均值的偏差超过三倍标准差的测定值,称为高度异常的离散值。
因为Selectivity和数据分布没有关系, 所以需要Outlier Selectivity来弥补它的不足。。比如上图中字段Sex, 因为取值有' M‘,' F‘两个值, selectivity就是50%。而图中“离散值选择性”是99.9667%,后栏中”离散值“是‘M’。 说明在1,000,000病人中, 绝大多数都是男性。 这个数据是我造的,真实环境中很难发生。 但其他的情况很常见,比如一个河南的医院数据中, 注册病人中可能99%都是河南的地址,那么当查询中包括“where address='河南' 和另一个查询 “where address=‘海南’'',SQL优化器会根据”离散值选择性“给出不同的执行计划。
- 平均字段大小(Average Field Size),
始于Cache2015.2 最后加入的统计指标,SQL引擎根据这个指标可以更好的计算查询计划中生成的临时文件的大小。
Map/索引的统计项
Map的意思是SQL表和硬盘数据之间的映射。Map有两种类型,Data/Master和索引,这里的统计项就是Block Count(块计数)
- Block Count(块计数)
始用于Caché 2013.1。 简单说, 就是表中的数据或者索引占多大的硬盘空间。
比如上图显示的IDKEY的行,它的类型是Data/Master,也就是表数据的大小是13627个Block。加上其他的索引。 每个BlockCount块的大小是2KB(和数据库的块大小无关),那么这个表数据占用硬盘就是大约27MB,每个索引占用的大小依次类推。
如果一个查询有多个合用的索引,SQL引擎会初步根据不同索引的Block Count, 选择小的那个。
Block Count还对SQL引擎对涉及父子表的查询的处理非常有用。