例如查询语句:
select user_id、username from t_user where username = "张三" and sex = 1;
其在MySQL的执行流程如下:
- 客户端发起查询请求,与SQL 接口建立连接,SQL 接口确定用户是否有查询权限,没有权限,直接返回错误信息,有执行下一步。
- 查询缓存(MySQL8.0 以前),以这条SQL语句为key在内存缓冲池中是否有结果,有直接返回结果,无则执行下一步。
- 解析器进行词法分析,提取出操作为select, 表名为 t_user, 查询字段为user_id、username,查询条件为username=“张三” 和 sex=1 ,把提取的Token转换为抽象语法树,接下来判断这个 sql 语句是否有语法错误,比如关键词是否正确等等,如果检查没问题就执行下一步。如下图:
- 优化器列出可能的执行方案:
接下来计算两个查询计划的成本,若username字段为索引,usrname和sex为联合索引、或查询条件可能致使索引失效,查询字段为*,造成成全表扫描,都有可能影响执行方案的选择。a. 先查询t_user表中username=“张三”的学生,然后判断是否性别为男。 b. 先找出学生中性别是男的学生,然后再查询username为“张三”的学生。
- 执行器进行权限校验,如果没有权限就会返回错误信息,如果有权限就执行器会调用数据库引擎接口,返回引擎的执行结果。
- 执行引擎根据执行计划查询数据,并把结果集返回客户端。
注意:
MySQL 8.0 取消了查询缓存是因为查询缓存对于高并发、大规模数据的应用程序效果不佳,甚至可能成为性能瓶颈。
-
查询缓存影响并发性能:MySQL在执行SELECT查询时,首先会去查询缓存中查找是否存在相同的查询语句和结果集,如果存在,则直接返回结果。然而,当并发用户越来越多时,这种缓存机制会导致大量请求阻塞在同一个锁上,从而降低了并发性能。
-
查询缓存占用大量内存:查询缓存将所有查询的结果存储在内存中,因此,当数据库中的数据量越来越大时,查询缓存会占用越来越多的内存,从而导致内存不足和OOM等问题。
-
查询缓存存在数据一致性问题:当数据表发生修改时,缓存中的数据可能就不再是最新的数据,而引入一致性问题。
总而言之,取消了查询缓存是为了提高数据库的性能和可靠性。MySQL 8.0引入了其他一些性能优化措施,如基于字节码的查询优化器、InnoDB缓冲池大小自动调整等,以提高数据库的性能和可靠性。