【发布时间】:2021-08-09 14:04:05
【问题描述】:
根据另一位开发人员在 stackoverflow 上的建议,我已将我的查询更新如下,但我仍需要进一步优化它。有人可以指导我如何最好地将索引应用于查询。
请参阅下面的查询:
SELECT a.id, a.user_unique_id, a.loan_location,
a.ippis, a.tel_no,
a.organisation, a.branch, a.loan_agree,
a.loan_type, a.appr, a.sold,
a.loan_status, a.top_up, a.current_loan,
a.date_created, a.date_updated, c.loan_id, c.user_unique_id AS tu_user_unique_id,
c.ippis AS tu_ippis, c.top_up_approved,
c.loan_type AS tu_loan_type, c.dse, c.status, c.current_loan AS tu_current_loan,
c.record_category, c.date_created AS tu_date_created,
c.date_updated AS tu_date_updated
FROM loan_applications_tbl a
LEFT JOIN topup_or_reapplication_tbl c
ON a.ippis=c.ippis
WHERE ((c.status IN ('pending', 'corrected', 'Rejected', 'Processing', 'Captured', 'Reviewed', 'top up')
AND MONTH(CURRENT_DATE) IN (MONTH(c.date_created), MONTH(c.date_updated)
AND YEAR(CURRENT_DATE) IN (YEAR(c.date_created), YEAR(c.date_updated))
AND c.current_loan='1' ))
OR ( a.loan_status IN ('pending', 'corrected', 'Rejected', 'Processing', 'Captured', 'Reviewed', 'top up')
AND MONTH(CURRENT_DATE) IN (MONTH(a.date_created), MONTH(a.date_updated)) )
AND YEAR(CURRENT_DATE) IN (YEAR(a.date_created), YEAR(a.date_updated))
AND (a.current_loan='1'
OR (a.current_loan='0'
AND a.loan_status IN('Approved','Closed')))))
执行时间:53s
记录数:11000
使用mysql EXPLAIN给出如下截图:(如何最大化可能的keys列中的信息
我已更新以下附加信息:
我在 c 和 a 之间使用 OR 的原因如下:
-
a是具有 66 列的父表,其中填充了贷款条目,如果a上的新条目具有匹配/现有的ippis(a上的唯一字段)a中的某些列被新条目中的数据更新/覆盖,而条目中的剩余数据作为新行插入c(ippis在表c中不是唯一的)。这是为了保留所有后续贷款请求的历史记录,同时不为冗余留出空间 -
在检索记录时,我需要大的
OR子句来检查a和c表中status, date and current_loan列与我的WHERE 子句中的参数匹配的每个贷款记录的所有实例。 -
a总是会有完整的记录,但c不会总是有记录,除非有更多相同唯一 ID 的贷款请求。a包含“谁是帐户人,例如通过唯一 ID”,以及第一次贷款的附加/补充状态详细信息,随后,在第一次贷款“c”之后将是附加/补充状态详细信息具有相同唯一 ID 的实际贷款申请。 -
如果“A”是在 3 月 12 日创建的,并且新的“c”记录是在 3 月 16 日创建的。“A”记录也会获得最后更新标记为 3 月 16 日,因为它的子附件包含对它有一些影响,而新的
c记录有它自己创建和更新的时间戳。a记录的更新字段将为空白/null,直到进行更改或存在c记录,c记录的更新字段将为空白/null,直到对c记录进行一些更改
我希望这是可以理解的
【问题讨论】:
-
where 子句中的
OR正在以一种糟糕的方式扼杀性能。您可以做几件事来使查询运行得更快,但OR必须放弃。 -
@matigo 非常感谢您的帮助。您介意帮助提供可能替代方案的伪代码吗?
-
您的查询在您的第一个 MONTH() 测试中放置了错误的近括号。应该是 MONTH(c.date_updated) ) 你有单身。然后,在您的 OR 条件之前删除一个 )。
-
@DRapp 感谢您的关注
-
@matigo 仍然期待您的帮助
标签: mysql datetime indexing query-optimization in-clause