对于目前技术栈使用 hibernate
框架来说,sql我是真的很少写的。然后这边目前我只知满足最左匹配是会走的,那么其他的索引上面的模糊查询就不会走。还有的就是IS Not Null也是不会走索引的,剩下的我就不清楚了呀!!
1. like '%abc' 或者 like‘%abc%’(不满足最左匹配) 2.where num/2=100 或者 subString(a,1,3)='ab'(索引参与表达式) 3. != 或者 <> 4. IS NOT NULL 5.关联查询的时候,主键类型与外键类型不一致 6.OR查询条件中存在没有索引的列 复制代码
这上面是我简单查询以及总结的不走索引的情况(情况可能暂时还是不够全面的,后期再继续补充)。当然走索引的话,其中要注意的是覆盖索引这种情况。以及(5.7?)版本出现的索引下推等情况。
这块我记得当时好像不止这两种方式。。。暂时还没有想起来(后期想到补充上去)
mysql创建复合索引的规则是首先会对复合索引的最左边的,也就是第一个字段的数据进行排序,在第一个字段的排序基础上,然后再对后面第二个字段进行排序。其实就相当于实现了类似 order by 第一个字段 第二个字段这样一种排序规则。
这种问题在之前的学习过程中,没有思考过。平时也只是知道哪种条件下会走索引,以及给哪些字段上面适合添加索引,当然的我是懵的。。这上面也是自己感觉出来的答案,有大佬的话可以再给我点回复。
这些东西在网上一搜一大把,但是面对我们很少手写sql的情况,我也是只是了解一些数据,对于大多数的没有操作过也不是很清楚。
table
:显示这一行的数据是关于哪张表的
type
:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL
possible_keys
:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句。这个列表是在优化过程的早期创建的,因此有些列出来的索引可能对于后续优化过程是没有用的。
key
: 实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,可以在SELECT语句中使用USE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MYSQL忽略索引
如果该索引没有出现在possible_keys中,那么mysql选用的是出于另外的原因——例如,他可能选择了一个覆盖索引,哪怕没有where字句,换句话说,possible_keys揭示了哪一个索引能有助于提高查询效率,而key显示的是优化采用哪一个索引可以最小化查询成本。
key_len
:使用的索引的长度。在不损失精确性的情况下,长度越短越好
ref
:显示索引的哪一列被使用了,如果可能的话,是一个常数
rows
:MYSQL认为必须检查的用来返回请求数据的行数
extra
:关于MYSQL如何解析查询的额外信息
其中Type列主要告诉我们对表使用的访问方式,主要包含如下集中类型:
all
:全表扫描。
const
:读常量,最多只会有一条记录匹配,由于是常量,实际上只须要读一次。
eq_ref
:最多只会有一条匹配结果,一般是通过主键或唯一键索引来访问。
fulltext
:进行全文索引检索。
index
:全索引扫描。
index_merge
:查询中同时使用两个(或更多)索引,然后对索引结果进行合并(merge),再读取表数据。
index_subquery
:子查询中的返回结果字段组合是一个索引(或索引组合),但不是一个主键或唯一索引。
rang
:索引范围扫描。
ref
:Join语句中被驱动表索引引用的查询。
ref_or_null
:与ref的唯一区别就是在使用索引引用的查询之外再增加一个空值的查询。
system
:系统表,表中只有一行数据;
unique_subquery
:子查询中的返回结果字段组合是主键或唯一约束。
实例化一个Bean--也就是我们常说的new;
按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;
如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值
如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以);
如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);
如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;
如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法;
注:以上工作完成以后就可以应用这个Bean了,那这个Bean是一个Singleton的,所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例,当然在Spring配置文件中也可以配置非Singleton,这里我们不做赘述。
当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;
最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
这上面描述的是Spring上下文的Bean周期,如果是工厂Bean的话,除去第五步操作即可。
从存储上面来说的话,在数据量大的情况下,B+树的设计可以允许数据分批加载。从查询上面来说,如果只是针对于一条查询,当然是hash比较快,但是我们大多数业务场景下面是多条查询,并且还是要进行排序返回的。此时如果范围查找的话就显得他是比较快的(因为节点是排序的,这时候就进行局部的中序遍历,可能要跨层访问。就能将数据查询返回出去)。
因为他是B+树,多路分支可以降低树的高度,提高查询效率问题,减少磁盘io次数。
它的叶子节点上面存储的是对应的聚簇索引地址以及数据本身,你在进行查询的时候,如果是利用的是主键等情况,则不需要进行回表操作,直接可以查询返回。
这上面是我印象中最深的几个问题,当然还有一些其他的问题。例如如何设计一个分布式锁、线程池的相关(这块我没回答好,感觉这里面需要考虑许多问题,不仅仅是源码中的代码)、 Map
中的key的hash是如何取值并且如果降低hash冲突(扰乱函数)等等。这些问题感觉最重要的还是数据库以及多线程,学习之路还长着呢。