看完《High Performance MySQL》前三章了,本来是计划上周总结一下的,但是硬要拖到现在。虽然只比《深入浅出MySQL》多了20+RMB,但是技术含量高太多了。前面三章讲的内容都算是比较琐碎和基础,第二章介绍的基准测试和性能分析工具有时间要去用一下。前两天还想着不总结的,因为都比较基础,但是这两天review了一下,有一些有意思的东西我觉得还是要写下来好点,不能给自己太懒。
MyISAM的索引是直接指向存储的数据行的物理位置,而InnoDB则是指向primary key,即是对于InnoDB而言,Key ‘im_a_index’ (id)这样的索引,其索引的数据里面指向的不是数据行的物理位置,而是数据行的primary key,因此使用索引查询其实会产生两次查询,首先是在索引里面获取查询数据的primary key,然后再通过primary key查询到真正的数据。因此,也出现了一个概念叫”Covering Index”,这个不是什么新鲜的概念,” An index that contains (or covers) all the data needed to satisfy a query is called a covering index. “,正是由于InnoDB要二次查询数据行的原因,covering index就让所有使用这个索引查询的数据都放在索引里面,对于”select * from table_name where …”这些要获取所有列的数据,那么就肯定会用不上这个covering index的好处了。当然,covering index也并不是鼓励所有的查询都新建一个index来体验covering index的好处,太多的index不但会使索引占用的容量增大难以维护,而且也会使update、delete、insert的成本提高很多,具体还是要看项目数据的需求而定,何况,一个数据访问量不大的小项目,就觉得没有什么必要了。对于B-Tree索引,应用索引除了要遵循leftmost prefix之外,在第一个range condition后面的列都不会应用到索引的,其实也就是索引会匹配这样的(equality, equality, range)这样的条件,但是在(equality, equality, range, equality, range..)这样的条件下,在第一个range后面的都不会享受到index的待遇。
” Clustered indexes aren’t a separate type of index. Rather, they’re an approach to data storage. The exact details vary between implementations, but InnoDB’s clustered indexes actually store a B-Tree index and the rows together in the same structure. “由于clustered index只是一种数据存储的方式,因此对于每个表只能拥有一个clustered index。目前支持这种建立索引的存储方式的只有solidDB和InnoDB支持。如果在InnoDB表中没有定义一个primary key,InnoDB会自动使用一个unique nonnullable index来替代primary key,如果没有这样的index,InnoDB将会隐式定义一个primary key,并此primary key上建立clustered index。” InnoDB stores each record immediately after the one before, because the primary key values are sequential. When the page reaches its maximum fill factor (InnoDB’s initial fill factor is only 15/16 full, to leave room for modifications later), the next record goes into a new page. “。
” Ordering the results by the index works only when the index’s order is exactly the same as the ORDER BY clause and all columns are sorted in the same direction(ascending or descending). “使用索引来排序与使用索引查询的约束差不多,只要WHERE和ORDER BY遵循leftmost prefix就基本可以了,ORDER BY子句的排序列不能是不同方向的排序。
MyISAM可以使用Prefix-Compressed的方式来建立Packed Indexes。” For example, if the first value is ‘perform’ and the second is ‘performance’, the second value will be stored analogously to ’7,ance’. “使用这种方式来建立索引,可以节约不少空间,” Packed indexes can be about one-tenth the size on disk. “。同时,这样可以使顺序扫描性能表现很好,但是使用反序扫描的话则会成为一个问题。实际上,这种索引的代价就是 CPU&Memory resources vs. disk resources。
对于这样的select语句” SELECT actor_id FROM table_name WHERE actor_id < 5 AND actor_id <> 1 FOR UPDATE “,(actor_id是索引)虽然返回的结果不包括actor_id=1的情况,但实际上在事务过程中InnoDB会把actor_id=1的行加锁。这说明了MySQL Server是在存储引擎返回了行之后再应用WHERE filter。关于InnoDB,indexes和locking还有一个鲜为人知的细节是,” InnoDB can place shared(read) locks on secondary indexes, but exclusive(write) locks require access to the primary key. That eliminates the possibility of using a covering index and can make SELECT FOR UPDATE much slower than LOCK IN SHARE MODE or a nonlocking query. “