马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
在数据库的利用中,各人时常会遇到慢SQL,或实行堕落的SQL。对于某些SQL题目,其错误缘故原由显而易见,但也有不少情况难以直观判断。面临这类题目,我们应当怎样应对?怎样正确辨认SQL错误的根源?是否须要优化SQL本身?照旧数据库的设置存在不敷?接下来,将扼要先容怎样敏捷定位SQL题目的战略。
但在深入探究之前,让我们先一同相识,当一条SQL语句进入OceanBase数据库体系实行时,它毕竟会颠末哪些模块和路径。
访问路径
起首我们从SQL的访问路径开始先容,一条SQL从应用发出之后,一样平常会颠末负载平衡(根据情况选择是否须要),然后到OBProxy,然后再到OBServer。大概流程如下图所示:
OBProxy重要起到一个路由转发的作用,以及快速分析,根据OceanBase数据库中数据副天职布情况,直接将哀求快速发送到对应的OBServer上。
SQL在进入OBServer之后,还会履历数据库内部很多模块,详细如下:
SQL的在数据库内部的实行过程,这些模块详细的寄义,可以参考官网文档:SQL 哀求实行流程,在整个SQL实行过程中,会起首根据SQL的ip、port、自增序列号等信息天生一个全局唯一的trace_id,后续的sql跟踪,我们都利用这个trace_id来对sql举行定位追踪。
SQL错误
这种题目一样平常都比力优点理,大多都是sql写的格式不对,大概库、表、列名等不存在,大概OceanBase语法不支持等,一样平常情况,根据返回的错误信息,就大抵可以判断堕落误缘故原由。
但也有一些很埋伏的错误,一时很难判断出详细是那边错了,这个时间就要借助错误日志 来资助我们举行判断了,这里就举一个例子,这是在一个用户那边实着实在遇到的题目,用户的场景比力复杂,拿OceanBase用来做数据的洗濯,将多张表举行关联盘算,然后将数据写入到结果表中,而在实行此中一条SQL过程中,收到了如许一个报错:
- ERROR 1292 (22007): Incorrect value
复制代码 当时用户收到这个报错后很茫然,由于用户的SQL长达200多行,而且有多层嵌套子查询和多张表关联查询,以是一时间很难判断出来是那边出现了错误,SQL大抵如下(脱敏后):
- REPLACE INTO abc.table1(
- m_id,
- st_id,
- con_id,
- `date`,
- t_ord,
- t_role,
- tag,
- con_pri,
- con_qu,
- con_in,
- update_time
- )
- SELECT
- tmp5.m_id,
- tmp5.st_id,
- tmp5.con_id,
- tmp5.`date`,
- tmp5.t_ord_96,
- tmp5.t_role,
- tmp5.tag,
- cast(sum(tmp5.con_pri) as decimal(20,6)) as con_pri,
- cast(sum(tmp5.con_qu) as decimal(20,6)) as con_qu,
- cast(sum(tmp5.con_in) as decimal(20,6)) as con_in,
- current_timestamp
- FROM
- (
- SELECT
- tmp4.m_id,
- tmp4.st_id,
- tmp4.con_id,
- tmp4.`date`,
- tmp4.t_ord,
- dstl2.t_ord_96,
- tmp4.t_role,
- tmp4.tag,
- case
- when tmp4.t_ord = dstl2.t_ord_96 then con_pri
- else 0
- end as con_pri,
- case
- when tmp4.t_ord = dstl2.t_ord_96 then con_qu
- else 0
- end as con_qu,
- case
- when tmp4.t_ord = dstl2.t_ord_96 then con_in
- else 0
- end as con_in
- FROM
- (
- SELECT
- tmp3.m_id,
- tmp3.st_id,
- tmp3.con_id,
- tmp3.`date`,
- tmp3.t_ord_96 as t_ord,
- tmp3.t_role,
- tmp3.tag,
- tmp3.con_pri,
- cast(tmp3.con_qu as decimal(20,6)) as con_qu,
- cast(tmp3.con_qu * tmp3.con_pri as decimal(20,6)) as con_in
- FROM
- (
- SELECT
- tmp2.m_id,
- tmp2.st_id,
- tmp2.con_id,
- tmp2.`date`,
- tmp2.t_ord_96,
- case
- when tmp2.con_name like '%xxx%' then 1
- when tmp2.con_name like '%x%' then 2
- when tmp2.con_name like '%xx%' then 3
- else
- case
- when tmp2.contract_type_name like '%xx%' then 4
- else 5
- end
- end as tag,
- case
- when tmp2.con_name like '%xxxxx%' then tmp2.vendee_price
- else tmp2.sale_price
- end as con_pri,
- case
- when tmp2.con_name like '%xxxxx%' then tmp2.vendee_energy
- else tmp2.sale_energy
- end as con_qu,
- tmp2.t_role
- FROM
- (
- select
- tmp.m_id,
- tmp.st_id,
- tmp.st_name,
- tmp.member_id,
- tmp.con_id,
- tmp.con_name,
- dd.`date`,
- tmp.t_ord_96,
- tmp.sale_energy / (datediff(tmp.timepart_endtime, tmp.timepart_starttime) + 1) / tmp.re as sale_energy,
- tmp.sale_price,
- tmp.vendee_energy / (datediff(tmp.timepart_endtime, tmp.timepart_starttime) + 1) / tmp.re as vendee_energy,
- tmp.vendee_price,
- tmp.timepart_starttime,
- tmp.timepart_endtime,
- tmp.seller_member_name,
- tmp.contract_type_name,
- tmp.t_role
- from
- (
- select
- tmp1.*,
- dstl.t_ord_96,
- count(1) over(PARTITION by member_id, con_id, time_division_range, timepart_endtime, timepart_starttime) as re
- from
- (
- select
- distinct
- spcdp.m_id,
- ds.st_id,
- ds.st_name,
- spcdp.member_id,
- spcdp.con_id,
- dc.con_name,
- spcdp.sale_energy,
- spcdp.sale_price,
- spcdp.vendee_energy,
- spcdp.vendee_price,
- spcdp.time_division_code,
- spcdp.time_division_name,
- case
- when dc.con_name like '%xx%' then
- case
- when substr(date_add(cast(concat('2022-10-01 ', right(spcdp.time_division_range, 5), ':00') as datetime), interval 1 hour), 12, 5) = '00:00' then concat(left(spcdp.time_division_range, 6), '24:00')
- else concat(left(spcdp.time_division_range, 6), substr(date_add(cast(concat('2022-10-01 ', right(spcdp.time_division_range, 5), ':00') as datetime), interval 1 hour), 12, 5))
- end
- else spcdp.time_division_range
- end as time_division_range,
- spcdp.timepart_endtime,
- spcdp.timepart_starttime,
- dc.seller_member_name,
- dc.contract_type_name,
- case
- when locate('x',dc.con_name) > 0 then 1
- when locate('x',dc.con_name) > 0 then 2
- else if(dc.con_qu>0,2,1)
- end as t_role
- from
- (select distinct m_id, member_id, con_id, sale_energy, sale_price, vendee_energy, vendee_price, time_division_code, time_division_name, time_division_range, timepart_endtime, timepart_starttime from
- select
- DISTINCT
- if(spcdp.m_id is null,spcdpa.m_id,spcdp.m_id) as m_id,
- if(spcdp.member_id is null,spcdpa.member_id,spcdp.member_id) as member_id,
- if(spcdp.con_id is null,spcdpa.con_id,spcdp.con_id) as con_id,
- if(spcdp.sa
复制代码 |