目录
一、为什么不建议使用外键索引?
外键通常都要求每次在修改数据时都要在另外一张表中进行一次额外的查询操作,虽然InnoDB强制外键使用索引,但还是无法消除这种约束检查的开销。如果外键的选择性很低,则会导致一个选择性很低的索引。
不过在某些场景下,外键会提升一些性能,比如想确保两个相关表始终有一致的数据,那么使用外键比在应用程序中检查一致性的性能要高的多,此外。外键在相关数据的删除和更新上,也比在应用中维护要更高效,不过,外键维护操作时逐行进行的,这样的更新会比批量删除和更新要慢些。
外键约束使查询时额外访问一些别的表,也就是需要额外的锁。如果向子表中写入一条记录,外键约束会让InnoDB检查对应的父表的记录,也就是需要对父表的对应记录进行加锁操作,来确保这条记录不会在这个事务完成之时就被删除了。这会导致额外的锁等待,甚至会导致一些死锁。因为没有直接访问这些表,所以这类死锁问题很难排查。
所以,在目前的很多项目中,为了性能的考虑,已经不使用外键了。
二、索引合并策略
1、当出现服务器对多个索引做相交操作时(通常有多个and条件),通常意味着需要一个包含所有相关列的多列索引,而不是多个独立的单列索引。
2、当服务器需要对多个索引做联合操作时(通常有多个or条件),通常需要耗费大量CPU和内存资源在算法的缓存、排序和合并操作上。特别是当其中有些索引的选择性不高,需要合并扫描返回的大量数据的时候。
索引合并看似是一种优化,实际上更多时候说明了表上的索引建的很糟糕。