等价替换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关键字在并发情况下性能较差。