前端请求的页面也能看出一些东西,帮助我们后端调试
Query String Parameters
请求参数,前端默认为page=0&size=10&sort=updateTime%2Cdesc&type=1
%2C是逗号的转义。
实体类的属性字段命名要用驼峰,数据库内可用下划线
待查询的sql语句:
1 | select city,name,age from t where city='杭州' order by name limit 1000 ; |
Sort_buffer_size定义:
Mysql为排序开辟的内存大小,如果要排序的数据量小于sort_buffer_size,排序就在内存中完成。但如果排序数据量太大,内存放不下,则不得不利用磁盘临时文件辅助排序。
通过查看 OPTIMIZER_TRACE,number_of_tmp_files表示排序使用的临时文件数,外部排序一般使用归并排序算法。MySQL 将需要排序的数据分成 12 份,每一份单独排序后存在这些临时文件中。然后把这 12个有序文件再合并成一个有序的大文件
- 初始化 sort_buffer,确定放入 name、city、age 这三个字段;
- 从索引 city 找到第一个满足 city=’杭州’条件的主键 id,也就是图中的 ID_X;
- 到主键 id 索引取出整行,取 name、city、age 三个字段的值,存入 sort_buffer 中;
- 从索引 city 取下一个City=’杭州’记录的主键 id;
- 重复步骤 3、4 直到 city 的值不满足查询条件为止,对应的主键 id 也就是图中的ID_Y;
- 对 sort_buffer 中的数据按照字段 name 做快速排序;
- 按照排序结果取前 1000 行返回给客户端。
该过程称为全字段排序
如果查询返回字段很多的,MySQL会将需要排序的列和主键放入sort_buffer,此时执行流程为:
- 初始化 sort_buffer,确定放入两个字段,即 name 和 id;
- 从索引 city 找到第一个满足 city=’杭州’条件的主键 id,也就是图中的 ID_X;
- 到主键 id 索引取出整行,取 name、id 这两个字段,存入 sort_buffer 中;
- 从索引 city 取下一个记录的主键 id;
- 重复步骤 3、4 直到不满足 city=’杭州’条件为止,也就是图中的 ID_Y;
- 对 sort_buffer 中的数据按照字段 name 进行排序;、
- 遍历排序结果,取前 1000 行,并按照 id 的值回到原表中取出 city、name 和 age 三个字段返回给客户端。
这个过程称为rowid排序,相比较全字段排序,它只取了排序字段和主键再内存中进行排序,排序结束后还需要遍历主键索引树,取出需要查询的值,这个回表的过程比较耗时。
总结就是:先把符合记录的字段取出来,再在sort_buffer中排序,如果全字段排序,排完序直接取出返回给用户端。如果不是全字段,只排序了一部分字段,则还需要遍历主键索引,取出需要查询的值。这个回表过程比较耗时
如果order by后面的字段走联合索引(两个或更多个列上的索引被称作复合索引。),联合索引中的数据有顺序的,比如(city, name, age)三个字段组成联合索引,会按照city排序,再按照name排序,最后按照age排序,这样查询的出的结果集可以直接返回,不需要使用sort_buffer内存进行排序,可以使用explain查看extra属性是否有Using filesort。
“message”: “could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement”,
参数有问题?