今天周五 上午上线的某个东西,为了开扩东南亚市场,
上线比较匆忙.在原来的系统上,增加了相关的国家查询.
上线后就有人喊慢,主要是业务人员常用的界面
SELECT c.custormer_country,so.*
FROM SALES_ORDERS SO
LEFT JOIN CUSTER_INFO C ON SO.customer_ID= c.customer_id
where 1=1
and so.time >= ?
and so.time <= ?
order by so.time desc
limit 0,10;
后台慢查询 最大时间为40秒,平均时间是20秒,打开RDS样本20条查询基本都是20多秒,少量是8-9秒.
点击几个SQL详细,发现时间的值都一样,默认7天.
也就是说这SQL 就是页面点击进去的默认查询SQL
昨天都好好的, 而且上周把SLAES_ORDERS订单去年的都迁移走了,
从周一到周四没有发现慢查询超过2秒的.
除了分页外, 还有金额统计. 另外个界面也有点慢 大约5秒的时间.
我把3个SQL 都拿出来.
除了1个SQL 执行计划有问题外,其它真的看不出来,简单的两表关联而已.
主表去LEFT JOIN 辅助表而已.
而这三个SQL 都是LEFT JOIN 同一个辅助表,就是它CUSTER_INFO
把它给注解掉,瞬间从20秒 降低到2.8秒
丢,不会是缓存的问题吧!
不该啊 !
再执行原来的SQL 注解前的, 结果还是19秒!
主和辅助表的关联字段 CUSTOMER_ID都有索引
执行计划用到了BNL
+----+-------------+-------+-------------------------------------+-------+----------------------------------+----------------------------------+---------+------+------+----------+---------------------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+-------------------------------------+-------+----------------------------------+----------------------------------+---------+------+------+----------+---------------------------------------------------------------------+
| 1 | SIMPLE | s | PAY_TIME_20220516,PAY_TIME_20220530 | range | pay_time_index | pay_time_index | 5 | NULL | 127 | 10.00 | Using index condition; Using where; Using temporary; Using filesort |
| 1 | SIMPLE | m | NULL | index | idx_sk_merchant_info_merchant_no | idx_sk_merchant_info_merchant_no | 788 | NULL | 73 | 100.00 | Using where; Using index; Using join buffer (hash join) |
+----+-------------+-------+-------------------------------------+-------+----------------------------------+----------------------------------+---------+------+------+----------+---------------------------------------------------------------------+
2 rows in set, 3 warnings (0.00 sec)
据说BNL 比普通的NJL 好! 主是在大数量情况下或者没有索引情况下.
nest join loop NJL
block nest loop BNL
简单说BNL 就是优化 连接字段(或者驱动表没有有用条件)没有索引 下的NJL。通过join buffer 来加快啊
BNL 是一种优化手动 BNL 用的join buffer 驱动表缓存在 join buffer 然后驱动一次驱动表。使用join buffer是因为 连接字段(或者驱动表没有有用条件)有索引。
理论上讲 选择BNL 优化器是没有问题的,
可实际情况不尽人意啊
群友提示下,会不会是字符集或者字符长度的问题
查询下两个表, SALES_ORDER 是UTF8MB4 而CUSTER_INFO 是UTF8
随后把CUSTER_INFO 修改成UTF8MB4 查询瞬间提升很高!
当驱动表的关联字段字符集高于被驱动的字符集 就会变得很慢.
开心周末!运动去!

近期文章
安装与原理
备份和恢复
主从复制
运维优化
SQL优化
mysql大量的waiting for table level lock怎么办
MYSQL开发
MYSQL分区维护
MGR集群
dba+开源工具:MySQL 8.0 MGR高可用VIP切换脚本
源码阅读
压测试工具
MYSQL 安全




