等价替换left join / right join查询
多表的left join
/ right join
关联查询性能较低,可以考虑等价替换为join
的SQL语句或者是用逗号分隔各个表,然后用where
条件替代on
条件作为关联条件的方式,关联查询多表(目前也推荐用逗号分隔,where
条件替代on
条件的方式进行多表内连接查询)。
例如对于同时符合以下设定的场景下:
- 如果A表为主表,B为从表。
- 其中,出参包含AB两个表的数据,查询的条件可能来源于A,B表。
- A表有记录,B表未必有记录。
- B表的code字段与A表的主键id字段关联。
- 各个查询条件之间是
AND
关系。
那么,查询SQL语句最直观地会写为:
select A.id, B.id from A left join B on A.id=B.code where ……
但是这样的SQL语句在宽表引擎下并非性能最佳, 可以等价替换为如下:
- 如果查询条件来源于A和B两表,并且查询条件都是
AND
逻辑拼接。可以改为:
select A.id, B.id from A, B where A.id=B.code and ……
- 如果查询条件只来源于A表,可改为使用以下的两条SQL:
select A.id from A where ……
将以上查询获取得到的A表的id传入到下列B表的SQL,查询获取B表的出参。
select B.id from B where B.code=?
- 如果查询条件只来源于B表,可以改为使用以下的两条SQL:
select B.id, B.code from B where ……
将以上查询获取得到的B表的code传入到下列A表的SQL,查询获取A表的出参。
select A.id from A where A.id=?
count查询不应该带order by
count
查询的目的是为了返回符合条件的总记录数,但是order by
则是对符合条件的记录进行排序,查询总数无需排序,排序则会增加非必要的耗时,应该在count
查询语句中删除order by
。
结合实际业务场景考虑是否在查询SQL中带有order by,count
如果模型中满足某条件的数据量很大,查询的SQL语句中带有order by
,count
过程非常缓慢。可结合自身业务场景考虑是否可以放弃。
如果业务上的 order by
,count
不能删除,可以通过以下的方案进行优化:
涉及count
的优化
由于count查询严重影响查询体验,所以可以考虑分情况讨论是否需要查询count
。count
一般用于前端分页展示选择页数,来进行分页选择查询。count
查询的优化方案,将脚本查询接口的count
输出改为可选输出,然后通过入参控制是否输出,如果需要输出再查询count
,否则不返回count
。
a. 对于页面上调用脚本的查询接口时,先试探查询传入start
=5000,limit
=5001,首次查询先通过入参控制不查询count
并且携带其他查询条件,如果返回记录不为空,则表示满足条件的记录大于5000条。
b. 如果能查出一条记录则表示记录超过5000,则后续的正常分页查询也不查询count
,只将分页查询的返回分页数据展示到页面上,页面也不展示count
。页面也只可以翻页到0~5000的记录,5000以上的无法看。
c. 如果查不到记录(表示满足条件的数量少于5000)。则可以正常返回count
,将返回的count
用于前端分页的总记录数量,此时返回的分页数据亦可以正常展示,用法与普通的分页查询用法一致。
多表关联不要使用select * 的方式返回对应字段的记录
由于多表关联字段的数量较多,如果是select *
,可能会返回很多不需要的字段记录,导致增加了非必要的数据传输。建议不要使用select *
,而是根据需要返回的字段一个个列出来,例如只需要id就写为select id
。
非必要场景下,避免使用distinct关键字进行记录去重
如果确定了返回的记录不会有重复的,应该避免使用distinct
关键字进行去重,distinct
关键字在并发情况下性能较差。