看了点有关MySQL索引和查询优化的知识,记录一下。
数据类型:
一些基本原则:更小通常更好;简单就好;尽量避免NULL(NULL难以优化可空列的查询,可以用0等值代替)
整数:TINYINT(8) SMALLINT(16) MEDIUMINT(24) INT(32) BIGINT(64)
实数:FLOAT(4) DOUBLE(8) DECIMAL(精确小数,适合金融数据等)
字符串:VARCHAR(变长,要2字节存储长度) CHAR(定长,适合很短的串或者长度近似相同的串,会把结尾的空格去掉)
BLOB和TEXT(不能索引完整长度,不能为排序使用索引)
ENUM(枚举类型,实际记录的是整数而不是字符串,与char和varchar join很慢)
日期和时间:DATETIME(8字节,范围大) TIMESTAMP(通常使用,4字节,范围小,UNIX时间戳,依赖时区)
(更精确的时间可以用BIGINT记录以毫秒为单位的时间戳)
特殊类型:IP地址(无符号的32位整数,有转换函数,也有用varchar(15)来存的)
索引:
索引类型:
B-Tree:按key的顺序讲数据顺序排列,列顺序极端重要。
适合匹配全名,匹配最左前缀,匹配列前缀,匹配范围值,精确匹配一部分并且匹配某个范围中的另一部分。
局限:查找必须从索引列最左边开始,不能跳过索引中的列,不能优化任何第一个范围条件右边的列。
Hash:按被索引列的哈希值进行索引,在数据库系统中不常见(memory引擎支持显式的哈希索引)。
特点:查找速度快
局限:不能使用哈希索引排序,不支持部分键匹配,只支持部分比较(=,<=>,IN()),碰撞很多会导致一些索引维护操作变慢。
可以利用触发器建立自己的哈希索引。(常用CRC32,因为SHA1和MD5太长)
空间索引和全文索引:MyISAM上的索引
高性能索引策略:
隔离列:隔离列意味着它不是表达式的一部分,也没有位于函数中。
前缀索引:对于索引很长的字符列,可以模拟哈希索引,或者建立前缀索引。(选择合适的前缀长度,例如计算全列的选择性,并使前缀的选择性接近于它)
聚集索引:一种存储数据的方式,数据行实际保存在索引的叶子页上。InnoDB按照主键进行聚集。(优点:可以把相关数据保存在一起,数据访问快,使用覆盖索引的查询可以使用包含在叶子节点中的主键值。缺点:插入速度依赖于插入顺序,更新聚集索引昂贵,聚集表比全表扫描慢)
比较InnoDB和MyISAM的数据布局
MyISAM中主键和键的索引没有区别,都是指向数据地址的指针。
InnoDB中数据时存在主键的索引中的(聚集索引),键的索引的叶子节点按键的顺序排列,每个叶子节点包括了主键的值作为指针(可以移动行而无须更新指针)。
InnoDB中,要以主键的顺序插入数据,并且要使用单调增的主键来插入新行。
覆盖索引:使用索引来接收列的数据,这样就可以不用读取行数据。
为排序使用索引扫描:按照索引对结果进行排序,只有当索引的顺序和ORDER BY子句中的顺序完全一致,并且所有列排序的方向(升降序)一样才可以。
前缀压缩索引:MyISAM使用。
重复索引和多余索引。
索引和锁定。