关于MySQL的执行过程:
1 MySQL中存在对SQL语句的改写,通过改写SQL达到优化SQL语句的目的,如将子查询改为关联查询.
2 MySQL并没有像Oracle 11g那样缓存执行计划,在Java开发中PreparedStatement接口对SQL进行预编译在默认情况下并没有发生.(即使开启也是在JDBC端缓存,数据库中并未缓存执行计划)
3 MySQL通讯协议是单向的,不同于Oracle.因为这一点,JDBC端只有在接收到所有查询结果后才会进行下一步操作.即在JDBC操作中只取出一条数据然后关闭ResultSet的做法,实际上并不会减轻网络通信负担.
4 MySQL会缓存查询结果,同时MySQL的连接和断开是轻量级的,所以在多数情况下,将一个复杂的查询切分为几个简单查询是非常有意义的.
*5 很多人认为where后面的条件顺序影响执行结果.在Oracle下因为会解析语方树,所以肯定是不会有影响的(Oracle解析语方树是从后往前解析的,之后再生成执行计划,所以存在两个错误的情况下后面的错误先报出来,会给人后面的语句先执行的错觉).个人认为因为MySQL也存在SQL优化,所以不会有影响.实际情况中确实会有影响,这是因为统计信息,估算成本不够准确,优化器认为两个条件约束力是相同的,所以按书写计划来执行.以上是本人关点未经验证.
关于性能测试:
select * from actor t where t.first_name='PENELOPE' and t.last_update>'1990-02-15 04:34:33' and 1=1;
/*查看消耗,在执行SQL语句后执行,可以获取执行后消耗,用于参考优化效果*/
show status like 'Last_query_cost';
/*查看执行计划*/
explain select * from actor t where t.first_name='PENELOPE' and t.last_update>'1990-02-15 04:34:33';
/*查看重构后的SQL,执行explain 后再执行show warnings可以看到优化器重写后的SQL*/
explain select * from actor t where t.first_name='PENELOPE' and t.last_update>'1990-02-15 04:34:33' and 1=1;
show warnings;
关于MySQL优化的思想:
<基于Oracle的SQL优化>中强调优"化SQL是基于SQL执行计划的深刻理解".
<高性能MySQL>中指出"创建高性能程序是一个环环相扣的难题,除了schema,索引和查询语句的设计,查询优化是解开难题的最后一步"
不要自以为比优化器更聪明
参考<高性能MySQL>,<基于Oracle的SQL优化>
结合<基于Oracle的SQL优化>一书,对部分细节进行补充.
本人工作经验主要以Java,Oracle为主,以这两方面为参考点来分析MySQL.
<高性能MySQL>中以MySQL 5.5为参考版本,再在MySQL已经到8.x版本,书中很多内容在MySQL5.7版本下测试结果与书中描述不符.
MySQL处于学习阶段,未接触过有大数据量的数据库,所以有些地方未详细确认