数据库学习之索引的总结

一、mysql使用索引的查询过程

                当查询语句里的where不包含索引或根据最左前缀匹配找不到的时候,数据库会根据主键索引顺序全表进行查找,找到对应的数据。查找的过程是在磁盘上进行磁盘I/O,这个过程是最消耗时间的,不过由于磁盘的预读取,消耗的时间会相对减少。

                当查询的语句里的where后包含索引的时候,数据库首先会通过辅助索引(辅助索引只是将索引列进行排序,这样的话所对应的主键就是无序的)找到对应的主键,然后根据主键去聚簇索引(主键+实际信息表)找这条信息进行比较,看是否符合where里的所有条件。查找的过程也是在磁盘上进行磁盘I/O,磁盘I/O的过程也包括预读取。但是由于这样查找的主键无序,所以这次预读取的数据不一定会包含下一条信息的主键,因此当数据量大的时候,很可能又会进行一次磁盘I/O,上述过程叫做随机I/O。数据量大的时候,随机I/O的次数很多,因此消耗的时间会很多。

                举个例子。一个表包含四列:id,sex,class,school。id:primary  key,sex:0-1,  class:0-10,  school:0-100。使用random随机创建400万条数据进行查询。

                查询语句:SELECT * FROM student WHERE sex=1 and class=5 and school=66

                不建索引(默认主键索引)的查询时间是1.2s   

                索引类型:sex:40s,class:33s,school:0.27s,sex+class:2.2s,sex+school:0.13s,sex+class+school:0.006s

                可以看出,只使用sex索引或者只使用class索引的时间非常久,因为按照上述的查找方法,这样查找的随机I/O次数(最差情况:sex:400w/2=200w次。class:400w//5=80w次,school:400w/100=4w次)很多,就会造成查询时间过长。时间次长的是sex+class,因为随机I/O次数(400w/(2×5)=40w次),根据数据也可以看出来,随机I/O次数跟查询时间大致是成正比的,随机I/O次数又是由索引列的数据的不同数量来确定的,不同数量越大,索引中满足条件的行数就越少,随机I/O次数就越少。而sex+class+school的查询时间很短,因为这是覆盖索引(索引列包含了所有需要查找的列),只需要在索引列上进行查找就能找到所有需要的信息,根本不需要去聚簇索引上面进行二次查找,也就不需要在聚簇索引上进行随机I/O。,因此所需要的时间最短。


二、mysql创建索引的总结

                当有一个表只允许创建一个索引的时候,创建所有列的组合索引,并且索引的顺序从单列不相等量最大值到最小值的顺序排列。

                索引优化最终要归结到随机I/O的次数,即如何创建索引能够让随机I/O的次数最少


三、mysql的查询大部分情况下是很智能的过程,但也有笨的情况。

                笨的情况在于:当有索引的情况下,只要根据最左前缀匹配原则能用到索引就肯定会使用索引,不论是否查询的快慢都会使用,所以上述例子中只创建sex索引,select * from students  where sex=1,mysql就会先去找sex索引,找到后再去找对应的数据,其实这样不如直接全表主键查询快,但是mysql无法判断。

                智能的情况在于:1、当有多个索引时,mysql会自动找到查询最快的索引。2、查询优化器的存在可以使where后的各种and随机互换而不影响查询效果。3、当覆盖索引中包含了select中的列的时候,就不需要再去聚簇索引中找数据了,直接在索引表中找到对应的数据输出就可以


猜你喜欢

转载自blog.csdn.net/a274537260/article/details/80006090