大概分为两种
单值索引(Single-Column Index)是指只有一个列作为索引键的索引。单值索引可以加速等值查询、范围查询和排序操作。在InnoDB中,B-tree索引是单值索引的常见类型。
复合索引(Composite Index)是指使用多个列作为索引键的索引。复合索引可以包含多个列,并按照指定的列顺序建立索引。复合索引的列顺序非常重要,因为查询只能从最左边的列开始并逐列往右匹配索引。复合索引可以提高多列查询的效率,但也会增加索引的大小和维护开销。
为了更好地理解单值索引和复合索引的区别,我们来看一个简单的例子。假设我们有一个包含两个列的表,分别是A和B。如果我们对A列创建了单值索引,那么查询条件中只使用A列的等值或范围查询时,索引将会被使用。但是,如果查询条件中同时使用A和B列,那么单值索引将无法有效地提供性能优势。这时候,我们可以考虑创建一个复合索引,按照A列和B列的顺序来建立索引。这样,在查询条件中使用A和B列时,复合索引可以更高效地进行匹配。
需要注意的是,在确定是否使用单值索引还是复合索引时,需要考虑查询的频率、表的大小、数据的分布等因素。合理选择合适的索引类型可以提升查询性能和减少存储空间的消耗。
在MySQL中,创建索引可以提高查询的性能,但同时也会增加写操作的开销和占用存储空间。因此,需要根据实际情况判断何时需要创建索引。
是么情况下需要创建
以下是一些常见的情况,适合创建索引:
-
主键和唯一键:通过创建主键或唯一键索引,可以确保表中的每一行都具有唯一值,提高数据完整性和查询效率。
-
频繁作为查询条件的列:如果某个列经常被用作查询的条件,那么创建索引可以加速查询操作。
-
JOIN操作的关联列:当表之间进行JOIN操作时,索引可以加速关联操作,特别是在关联列的数据量较大时。
-
排序和分组的列:对于经常需要排序和分组的列,创建索引可以提高查询的性能。
需要注意的是,创建索引并不适用于所有情况。以下是一些不适合创建索引的情况:
-
对于小型表:对于一些非常小的表,创建索引的开销可能会超过查询的性能提升。
-
经常进行大批量更新或插入的表:由于创建索引需要维护索引的数据结构,大量写操作会增加索引的维护开销,导致性能下降。
-
数据分布不均匀的列:如果某个列的值在整个表中分布非常均匀,那么创建索引可能无法提供明显的性能提升。
总之,创建索引是一个权衡性能和存储空间开销的过程,需要根据具体的业务需求和数据特点进行判断。
索引失效情况
索引在一些特定情况下可能会失效,导致查询性能下降。以下是一些常见的索引失效情况:
-
不使用索引列:如果查询中没有使用索引的列,那么该索引将不会起作用。
-
未适当使用索引:有时候,查询中使用了索引列,但是查询条件不是很准确,导致索引无法起到优化查询的作用。例如,使用了索引列进行范围查询或使用了函数、表达式或类型转换来操作索引列。
-
使用LIKE查询时,以通配符开头:%或_等:如果查询中使用了LIKE操作符,并且通配符%或_出现在查询字符串的开头,那么索引通常将无法使用。
-
对索引列进行了函数操作:如果在查询中对索引列进行了函数操作,例如使用了DATE_FORMAT或LOWER等函数,那么索引可能无法使用。
-
组合条件时,未使用索引最左前缀:当使用复合索引时,索引的最左前缀必须被包含在WHERE条件中,否则索引将无法使用。例如,对于复合索引(a, b, c),查询条件“WHERE b = 1 and c = 2”可以使用索引,而“WHERE c = 1 and a = 2”则无法使用索引。
-
表中数据分布不均匀:如果表中数据分布极端不均匀,某些值的重复率过高(例如,某个列的值只有两种可能),那么索引可能无法提供明显的性能优势。
建议在创建索引时,考虑到查询的使用方式、查询条件的准确性、列的数据类型和数据分布等因素,以提高索引的使用效果。
最左前缀
最左前缀指的是复合索引中,查询条件中使用到的索引列必须是索引的最左边的列开始的连续子集。这意味着如果有一个复合索引(a, b, c),那么查询条件必须至少包含a列。
举个例子,假设有一个表(students)包含以下列和数据:
id | name | age | grade |
---|---|---|---|
1 | Alice | 18 | A |
2 | Bob | 17 | B |
3 | Carol | 18 | A |
4 | David | 17 | C |
如果我们创建了一个复合索引(grade, age),那么以下查询可以使用索引:
- SELECT * FROM students WHERE grade = 'A' AND age = 18
- SELECT * FROM students WHERE grade = 'B' AND age = 17
但是以下查询无法使用索引:
-
SELECT * FROM students WHERE age = 18 这个查询没有使用到索引的最左边的列(grade),因此索引将无法被利用。
-
SELECT * FROM students WHERE age = 18 AND grade = 'A' 查询条件中的列顺序与复合索引的顺序不一致,因此索引将无法被利用。
需要注意的是,虽然查询条件中可以包含复合索引的所有列,但是如果查询条件中没有按照最左前缀的顺序使用索引列,那么索引也无法被利用。因此,在创建复合索引时,需要根据常见的查询条件和查询顺序来考虑索引列的顺序。