我在工作中遇到了一点问题,ORM 正在生成一个非常奇怪的查询,我需要稍微优化它的结果。我写了一个更具可读性的查询版本,结果相似,但执行时间仍然相同。
这是当前格式化的查询,它返回正确的值,但执行大约需要 13 秒。
select count(*)
from reservation as r
JOIN companyclient as cc ON r.companyclientid = cc.companyclientid
JOIN reservationitem as ri ON r.reservationid = ri.reservationid
LEFT JOIN billingaccount as bi
ON (r.reservationid = bi.reservationid AND cc.companyclientid = bi.companyclientid AND
bi.propertyid = '84'
AND NOT bi.isdeleted
AND bi.groupkey = bi.billingaccountid
AND bi.billingaccounttypeid = '3'
AND bi.reservationid IS NOT NULL
AND bi.statusid = '1')
WHERE r.propertyid = '84'
AND NOT r.isdeleted
AND r.companyclientid is not null
AND ri.tenantid = '025aa64f-67fb-4c23-b975-2b0fc3f5d65a'
AND NOT ri.isdeleted
AND ri.reservationitemstatusid NOT IN (6, 3, 7, 8);
这是我写的尝试优化的版本(从13秒到5秒),避开了left join里面的条件,但是结果和原来的查询不一样。第一个查询返回 29490,第二个查询返回 29397。
select count(*)
from reservation as r
JOIN companyclient as cc ON r.companyclientid = cc.companyclientid
JOIN reservationitem as ri ON r.reservationid = ri.reservationid
LEFT JOIN billingaccount as bi
ON (r.reservationid = bi.reservationid AND cc.companyclientid = bi.companyclientid)
WHERE r.propertyid = '84'
AND NOT r.isdeleted
AND r.companyclientid is not null
AND ri.tenantid = '025aa64f-67fb-4c23-b975-2b0fc3f5d65a'
AND NOT ri.isdeleted
AND ri.reservationitemstatusid NOT IN (6, 3, 7, 8)
AND (bi is null or bi.propertyid = '84'
AND NOT bi.isdeleted
AND bi.groupkey = bi.billingaccountid
AND bi.billingaccounttypeid = '3'
AND bi.reservationid IS NOT NULL
AND bi.statusid = '1')
我的问题是,如何优化第一个查询,我尝试了一些方法,但没有取得多大成功。我知道计数是线性的,它的时间基于查询返回的大小,但我认为对于 30K 行查询来说太慢了。
在这种特定情况下,我需要项目总数来计算限制偏移分页中的页数。
提前感谢所有耐心阅读的人,我接受任何帮助。
示例中使用的表大小:
- 预留:288549 行
- companyclient: 50614行
- 预留项:387820 行
- 计费帐户:772521 行