假设我们有一个查询语句: select * from profiles where sex = 1 and age > 18 and country = 'china' 现在为了优化查询性能,有的人可能会直接给where条件中的每个字段都单独加索引,但是一条查询语句中mysql只会用一个索引,记录数最少的那个,这就有点浪费了。 如果说我们创建了一个复合索引 sex_age_country,就相当于这条语句同时利用了三个索引,前提是查询语句必须满足最左前缀原则,即查询条件必须包含sex字段。 单键索引就不说了。 至于btree和hash是索引的存储结构,通常索引就是btree类型,它是树结构,保存了列值以及对应行的指针等,树能减少查找时间,hash就是对索引列的值生成一个唯一的hash值,每个hash中只保存行指针,索引列的值有重复,那就会出现hash碰撞,这些重复的行指针会以链表的形式存储在同一个hash中,此外hash索引不保存列的值,也就是说就算匹配到了hash索引,也需要通过指针去对应的行读取数据,另外hash索引只支持等值匹配,不支持范围查询,不支持排序等,总之限制很多,而且索引列重复值太多的话也会造成性能问题。 通常,我们都使用btree类型的索引,以上是我的浅见。
假设我们有一个查询语句:
现在为了优化查询性能,有的人可能会直接给where条件中的每个字段都单独加索引,但是一条查询语句中mysql只会用一个索引,记录数最少的那个,这就有点浪费了。
如果说我们创建了一个复合索引 sex_age_country,就相当于这条语句同时利用了三个索引,前提是查询语句必须满足最左前缀原则,即查询条件必须包含sex字段。
单键索引就不说了。
至于btree和hash是索引的存储结构,通常索引就是btree类型,它是树结构,保存了列值以及对应行的指针等,树能减少查找时间,hash就是对索引列的值生成一个唯一的hash值,每个hash中只保存行指针,索引列的值有重复,那就会出现hash碰撞,这些重复的行指针会以链表的形式存储在同一个hash中,此外hash索引不保存列的值,也就是说就算匹配到了hash索引,也需要通过指针去对应的行读取数据,另外hash索引只支持等值匹配,不支持范围查询,不支持排序等,总之限制很多,而且索引列重复值太多的话也会造成性能问题。
通常,我们都使用btree类型的索引,以上是我的浅见。