加强网站建设 通知,网站要和别人做api 链接,在线美工,html代码大全简单最近的一个大屏报表统计的接口查询速度很慢#xff0c;耗时近一分钟左右#xff0c;数据量级只是700万左右#xff0c;但很慢#xff0c;最后优化到4秒左右#xff0c;客户还能接受#xff0c;但其实还可以在优化#xff0c;先这样吧#xff0c;简单记录下。这次主要优…最近的一个大屏报表统计的接口查询速度很慢耗时近一分钟左右数据量级只是700万左右但很慢最后优化到4秒左右客户还能接受但其实还可以在优化先这样吧简单记录下。这次主要优化的部分数据库和Java代码部分前端的很少。 一、数据库
优化先从浏览器的接口调用看查看到耗时近1分钟根据接口名称查询对应的Java代码发现代码中存在两个SQL的调用顺着引用找到SQL语句一看是两个都是关联查询的SQL其中一个还是关联了5张表复制出来后到SQL端执行确实很慢。
数据库优化很好用的两个命令是EXPLAIN和EXPLAIN ANALYZE命令都是加载查询语句前面用于分析查询计划和查询实际执行情况的。 然后是使用EXPLAIN命令查看查询计划的的信息判断是否有需要添加或修改的索引。
使用案例
---只需将 EXPLAIN 关键字加在查询语句开头就行 EXPLAIN SELECT COUNT(DISTINCT h.id)
FROM test h
JOIN test2 s ON h.id s.father_id
WHERE s.first_classify QC ;
执行结果示例 EXPLAIN 命令可以用来分析 SQL 查询语句的执行计划它返回一组字段信息提供了有关查询的重要性能指标和执行计划的详细信息。下面是 EXPLAIN 命令返回的字段信息的介绍 id查询的标识符用于标识查询中的每个操作步骤。如果查询有多个操作步骤id 可能会有多个数字表示操作步骤的执行顺序。 select_type操作步骤的类型表示查询的类型。常见的类型有 SIMPLE简单查询、PRIMARY主查询、SUBQUERY子查询、DERIVED派生表查询等。 table操作步骤涉及的表的名称。 partitions操作步骤使用的分区。 type访问表的方式表示查询使用的访问方法。常见的类型有 const常量表、eq_ref唯一索引查找、ref非唯一索引查找、range范围查找、index索引扫描、all全表扫描等。一般来说访问方法从最好到最差的顺序是const、eq_ref、ref、range、index、all。 possible_keys可能应用于该操作步骤的索引列表。 key实际应用于该操作步骤的索引。 key_len索引字段的长度。 ref操作步骤使用的索引字段或常量与表之间的关联。 rows操作步骤扫描的行数估计。 filtered操作步骤的行过滤百分比。 Extra附加信息提供了关于操作步骤的其他信息例如是否使用了临时表、是否使用了文件排序等。 这些字段信息可以了解查询的执行计划和性能瓶颈从而进行性能优化和调整。通过分析这些信息可以确定是否需要添加索引、优化查询条件、重构查询语句等来提高查询性能。
不同的数据库管理系统如MySQL、PostgreSQL等可能会略有不同的字段信息和含义。
关键信息是type类型尽量少用全表扫描。possible_keys在适合的字段上加上索引。索引的是使用是用空间换时间。
下面是使用EXPLAIN ANALYZE 命令执行查询结果分析
---只需将 EXPLAIN ANALYZE 关键字加在查询语句开头就行 EXPLAIN ANALYZE SELECT COUNT(DISTINCT h.id)
FROM test h
JOIN test2 s ON h.id s.father_id
WHERE s.first_classify QC ;
执行结果如果你看不懂可以直接把查询结果丢给ChatGPT让它给你分析并逐行注释。 - Aggregate: count(distinct h.id) (cost1193743.16 rows1) (actual time4594.609..4594.609 rows1 loops1)- Nested loop inner join (cost824307.99 rows3694352) (actual time0.359..2941.550 rows1277716 loops1)- Covering index scan on h using id_idx (cost33565.75 rows257665) (actual time0.136..76.075 rows272267 loops1)- Covering index lookup on s using idx_father_id_first_classify (father_idh.id, first_classifyF41A01) (cost1.64 rows14) (actual time0.008..0.010 rows5 loops272267)EXPLAIN ANALYZE 命令是一种用于分析 SQL 查询语句执行计划和实际执行时间的命令。它返回的字段信息包括 EXPLAIN 命令的字段信息同时还包括以下字段 QUERY PLAN查询执行计划的详细信息包括操作步骤、访问方法、索引使用等。 Planning Time查询规划阶段的时间表示生成查询执行计划所花费的时间。 Execution Time查询执行阶段的时间表示实际执行查询所花费的时间。 Actual Rows实际扫描的行数表示查询实际扫描的行数。 Actual Loops实际循环次数表示查询实际执行的循环次数。 Actual Startup Time实际开始执行查询的时间。 Actual Total Time实际执行查询的总时间。 Actual Time实际执行查询的时间以毫秒为单位。 EXPLAIN ANALYZE 命令返回的字段信息可以帮助您更全面地了解查询的执行计划和实际执行情况。通过分析这些信息可以确定查询的性能瓶颈、优化查询计划、减少查询执行时间等。同时还可以比较不同查询语句的执行效果选择性能最佳的查询方式。
最后通过ANALYZE TABLE 命令来优化下对应的表
---只需将 EXPLAIN TABLE 关键字加在表名开头就行
ANALYZE TABLE test;
ANALYZE TABLE 命令是用于分析和收集数据库表统计信息的命令。它的主要作用是帮助优化查询性能和执行计划。
ANALYZE TABLE 命令会完成以下任务 优化查询计划通过分析表的统计信息数据库管理系统可以更准确地估计查询的成本和选择最优的执行计划。 选择合适的索引通过分析表的索引长度和数据分布情况可以判断是否需要创建或删除索引以及选择合适的索引类型和列顺序。 优化存储空间通过分析表的行数和平均行长度可以估计表的总大小并根据需要进行存储空间的调整。 检测表的完整性通过分析更新时间和自增值可以检测表的数据是否完整并及时发现可能存在的问题。 数据库的查询通过加索引大部分都能解决在这个过程中善于用ChatGPT来帮助解决很重要。
二、Java程序代码
下面是程序代码的部分原本的程序代码并不是我写的打开看了之后有两个执行查询的代码段是可以同时执行的所以改成并发执行。 程序上改后接口时间就减少一半了接口时间来到了4.5秒左右但其实还是慢。
三、前端React代码
在改改前端前端的话可以把这个接口的查询放在最开始执行以减少用户使用的等待延迟感受。前段端代码就省略了。下次有机会在写吧。 四、总结拓展
性能优化某种意义上是对资源取舍利用的问题。通常是就是空间和时间的互换与取舍。
以下是我收集到的常见的6种互换手段。 1、索引 索引的原理是拿额外的存储空间换取查询时间增加了写入数据的开销但使读取数据的时间复杂度一般从O(n)降低到O(logn)甚至O(1)。
在数据集比较大时不用索引就像从一本没有目录而且内容乱序的新华字典查一个字得一页一页全翻一遍才能找到用索引之后就像用拼音先在目录中先找到要查到字在哪一页直接翻过去就行了。书籍的目录是典型的树状结构。 2、缓存 缓存优化性能的原理和索引一样是拿额外的存储空间换取查询时间。Phil Karlton 曾说过计算机科学中只有两件困难的事情缓存失效和命名规范。缓存的使用除了带来额外的复杂度以外还面临如何处理缓存失效的问题。 3、压缩 压缩的原理消耗计算的时间换一种更紧凑的编码方式来表示数据。对数据的压缩虽然消耗了时间来换取更小的空间存储但更小的存储空间会在另一个维度带来更大的时间收益。
能减少的就减少 JS打包过程“摇树”去掉没有使用的文件、函数、变量 开启HTTP/2和高版本的TLS减少了Round Trip节省了TCP连接自带大量性能优化 减少不必要的信息比如Cookie的数量去掉不必要的HTTP请求头 更新采用增量更新比如HTTP的PATCH只传输变化的属性而不是整条数据 缩短单行日志的长度、缩短URL、在具有可读性情况下用短的属性名等等 使用位图和位操作用风骚的位操作最小化存取的数据。典型的例子有用Redis的位图来记录统计海量用户登录状态布隆过滤器用位图排除不可能存在的数据大量开关型的设置的存储等等。
能删除的就删除 删掉不用的数据 删掉不用的索引 删掉不该打的日志 删掉不必要的通信代码不去发不必要的HTTP、RPC请求或调用轮询改发布订阅 终极方案砍掉整个功能。 4、预取 预取通常搭配缓存一起用其原理是在缓存空间换时间基础上更进一步再加上一次“时间换时间”也就是用事先预取的耗时换取第一次加载的时间。
当可以猜测出以后的某个时间很有可能会用到某种数据时把数据预先取到需要用的地方能大幅度提升用户体验或服务端响应速度。 5、削峰填谷 削峰填谷的原理也是“时间换时间”谷时换峰时。
削峰填谷与预取是反过来的预取是事先花时间做削峰填谷是事后花时间做。就像三峡大坝可以抗住短期巨量洪水事后雨停再慢慢开闸防水。软件世界的“削峰填谷”是类似的只是不是用三峡大坝实现而是用消息队列、异步化等方式。 6、批量处理 批量处理同样可以看成“时间换时间”其原理是减少了重复的事情是一种对执行流程的压缩。以个别批量操作更长的耗时为代价在整体上换取了更多的时间。 前端把所有文件打包成单个JS大部分时候并不是最优解。Webpack提供了很多分块的机制CSS和JS分开、JS按业务分更小的Chunk结合懒加载、一些体积大又不用在首屏用的第三方库设置external或单独分块可能整体性能更高。不一定要一批搞定所有事情分几个小批次反而用户体验的性能更好。 Redis的MGET、MSET来批量存取数据时每批大小不宜过大因为Redis主线程只有一个如果一批太大执行期间会让其他命令无法响应。经验上一批50-100个Key性能是不错的但最好在真实环境下用真实大小的数据量化度量一下做Benchmark测试才能确定一批大小的最优值。 MySQL、Oracle这类RDBMS最优的批量Insert的大小也视数据行的特性而定。我之前在2U8G的Oracle上用一些普遍的业务数据做过测试批量插入时每批5000-10000条数据性能是最高的每批过大会导致DML的解析耗时过长甚至单个SQL语句体积超限单批太多反而得不偿失。 消息队列的发布订阅每批的消息长度尽量控制在1MB以内有些云服务商提供的消息队列限制了最大长度那这个长度可能就是性能拐点比如AWS的SQS服务对单条消息的限制是256KB。 还有与提升并行能力有点关的4中方式 榨干计算资源水平扩容分片无锁 参考文献
性能优化的 10 个技巧文末送书