1、索引
mysql基本的索引都是使用B-tree系列来进行存储,例如PK、建表时的INDEX、UNIQUE约束。InnoDB使用的是B+树来存储索引信息。
mysql对索引的使用较广:
a、找到对应的行
b、简化数据查询量,一次查询中有多个索引可用时,会选择对应数据更少的那个
c、在sort操作中,对group by的指定字段使用索引来进行计算
覆盖索引的理解:
覆盖索引是一种对于索引的使用方式,可以理解为在进行某些查询时,可以直接通过索引就能查询到所需要的字段,这样就不需要再去读数据行,可以大大提升数据查询的效率。
隐式索引:MySQL对于主键和唯一约束是通过索引来实现的,因此在数据表中对某一列添加唯一约束后,就已经在这一列上创建了索引。
2、数据的组织形式
数据的具体组织形式与实用的数据库引擎有关,InnoDB是将数据按照主键存储的聚簇索引。
主键的聚簇索引的意思,就是主键索引B+树的叶子节点中,会存储具体想的数据行信息。所以,叶子节点中的数据,都是已经按照主键做了排序的。所以,聚簇索引就是表本身。
MySQL的MyISAM引擎本身是不支持聚簇引擎的,所以对于MyISAM来说,它的主键和其它的索引没有太大的区别。
其它索引各有自己的B+树的存储实现,但它们的叶子节点中存放的是主键的值,也就是说,对于一般的索引的查询,需要经过两次查询才能找到数据。先通过索引找到主键值,然后再通过主键去查询行数据.
聚簇索引和非聚簇索引的区别,以及在物理存储上的实现,可用下面的图来表示。
3、索引和锁
MyISAM引擎不支持行锁,InnoDB引擎能支持行级锁。
InnoDB只有在访问行的时候才会对其加锁,索引能够减少InnoDB访问的行数,从而减少锁的数量。
InnoDB在二级索引上使用共享锁(读)锁,但访问主键索引需要排他(写)锁。
5、MySQL的关联查询模型
这里所说的关联是一种更广泛意义上的关联,可以认为每一次查询都是一次"关联"操作。
MySQL的关联查询策略描述如下:
MySQL对任何关联都执行嵌套循环关联操作,即MySQL先在一个表中循环取出单条数据,然后再嵌套循环到下一个表中寻找匹配的行,依次下去,直到找到所有表中匹配的行为止。然后根据各个表匹配的行,返回查询中需要的各个列。
即,先到外层表中找到符合条件的行,然后对于这里找到的每一行,分别与内层表中的数据进行match
对于下面这条关联查询语句
SELECT tbl1.col2,tbl2.col2 FROM tbl1 INNER JOIN tbl2 USING(col3) WHERE tbl1.col1 IN(5,6)
可以将其转成伪代码的形式来解释MySQL的关联查询策略
outer_iter = iterator over tbl1 where col1 IN(5,6)
outer_row = outer_iter.next
while outer_row
inner_iter = (iterator over tbl2 where col3 = outer_row.col3)
inner_row = inner_iter.next
while inner_row
output [outer_row.col2,inner_row.col2]
inner_row = inner_iter.next
end
outer_row = outer_iter.next
end
对于单个表的查询,也可以用上面这个策略来覆盖,只是在这种情况下没有了内层表的参与
如果将mysql改成左外连接
SELECT tbl1.col2,tbl2.col2 FROM tbl1 LFET OUTER JOIN tbl2 USING(col3) WHERE tbl1.col1 IN(5,6)
改成伪代码的形式后,结果如下,与上面部分的差别在于if -- else 语句的引入
outer_iter = iterator over tbl1 where col1 IN(5,6)
outer_row = outer_iter.next
while outer_row
inner_iter = (iterator over tbl2 where col3 = outer_row.col3)
inner_row = inner_iter.next
if inner_row
while inner_row
output [outer_row.col2,inner_row.col2]
inner_row = inner_iter.next
end
else
output [outer_row.col2, NULL]
end
outer_row = outer_iter.next
end
[mysql数据库表的数据一致性]
[mysql集群方案]
ps: 内容来自《高性能MySQL》