摘要:
最近在处理stonedb的一个包含内连接包含内连接外连接派生表in子查询和聚合的查询出错的问题, 逻辑非常复杂, 包含的操作符非常多.
本文首先从顶层设计出发, 指出如何分析如此复杂的问题。
查询SQL:
SELECT
B.company_id,
'上划日' ud_type,
2 sort_no,
'合计' fiscal_date,
DATE_FORMAT('2023-06-06', '%Y-%m-%d') fiscal_date,
C.pl_amount
FROM
C1FG_POOL A
INNER JOIN C1FG_PL_NODE B ON
A.row_id = B.pool_id
LEFT JOIN (
SELECT c.node_id,
SUM(d.dr_amount) pl_amount
FROM
C1FG_POOL a,
C1FG_PL_NODE b,
C1FG_PL_ACCOUNT c,
C1FG_PL_SUBSIDIARY d
WHERE
a.row_id = b.pool_id
AND b.row_id = c.node_id
AND c.row_id = d.account_id
AND b.company_id IN (
SELECT t1.row_id
FROM
C1MD_COMPANY t1,
C1MD_COMPANY t2
WHERE
t1.sys_id = t2.sys_id)
GROUP BY
c.node_id) C ON
B.row_id = C.node_id;
查询出错的SQL总体概览:
- 即使经过逻辑精简后的SQL,也依然十分复杂
- 总共涉及的表有7个之多
- 表之间的连接关系包括内连接和外连接
- 外连接的右表, 是一个派生出来的表
- 派生表中存在in的子查询
- 派生表中存在聚合
分析该复杂SQL的方法:
一. 通过debug模式下的trace日志分析查询执行的细节
2022-10-18 mysql-5.7-开启debug日志_mysql 开启debug日志_财阀悟世的博客-CSDN博客
二. 通过trace分析查询优化处理器的优化细节
2023-02-24 mysql-开启optimizer trace_财阀悟世的博客-CSDN博客
三. 查询优化的相关理论
- 代价计算
- 子查询优化的策略
- 外连接的优化场景和策略
- 内连接的优化场景和策略
- 聚合的优化策略
四. 查询执行的相关细节
- 查询树的元素
- select_lex, table, item, cond, field...
- 表连接相关的数据结构
- TABLE, JOIN_TAB, st_table_join...
- 查询执行的相关数据结构
- JOIN, QEP_TAB
- 查询优化的核心函数
- JOIN::optimize
- 查询执行的核心函数
- sub_select
- evaluate_join_record
一些草图: