我需要加快以下查询的执行时间,因为执行时间太长,我认为子查询就是问题
SELECT WFApplication.*,
WorkflowIncidentType.TypeName ProcessCategory,
WFProcess.WFProcessName ProcessName,
LUTAppStatus.EnglishName AppStatus
FROM WFApplication
INNER JOIN LUTAppStatus ON WFApplication.ApplicationStatus = LUTAppStatus.Id
INNER JOIN WorkflowIncidentType ON WorkflowIncidentType.TypeID = WFApplication.ApplicationIncidentType
INNER JOIN WFProcess ON WFProcess.WFProcessId = WFApplication.ApplicationProcess
LEFT OUTER JOIN IBSCustomer ON IBSCustomer.RIM = WFApplication.RIM
LEFT OUTER JOIN Reschedule ON Reschedule.RescheduleId = WFApplication.ProcessId
WHERE WFApplication.ProcessId IN
(SELECT ProcessId
FROM WFProcessInstanceLog)
AND WFProcessInstanceId IN (28251,
28345,
28773,
28774,
28846,
29309, .....)
答案 0 :(得分:2)
好的,这是查询SQL性能优化的基础。
第一步:显示实际执行计划。在“查询”菜单中,选中“包括实际执行计划”。然后,当您运行查询时,结果窗格中将显示一个额外的标签,用于“执行计划”。
第二步:查看树中最右边的节点。通常会有四种可能性:
现在,是什么原因导致SQL选择一个选项而不是另一个?首先重要的是您的索引。通常,“执行计划”会提醒您缺少索引,这些索引会提高查询的性能。但是您可以手动查看-如果使用完整扫描正在通过“表A” ...为什么?查找,搜索或匹配哪个列?很有可能,该列需要有一个索引,以便引擎可以快速对其进行匹配。
但是还有其他原因。可以说表没有那么大,并且您要在表上匹配很多条目。对于SQL来说,仅浏览整个表可能会更快。
另一个经常被忽略的原因:您在相关列上有索引,但是它们没有将数据缩小到足以使它们有价值的地步-或者,它正在查看许多不同的索引以试图纠缠它们与原始表相比,所有操作都比仅使用大型表慢。在这种情况下,解决方案是创建索引中包含多个列的索引。
诊断此类问题的一种好方法是忽略某些表/数据,并查看执行计划是否发生了变化。例如,尝试以下查询:
SELECT WFApplication.*
FROM WFApplication
WHERE WFProcessInstanceId IN (28251,
28345,
28773,
28774,
28846,
29309, .....)
执行计划是否更改?如果以上语句中的计划不正确,则可能意味着您缺少WFProcessInstanceId上的索引,或者您的表不足以对主表提供5000个引用。
但是,如果它在该查询上使用索引查找,但是在添加其他表时切换到“扫描”操作,则可能表明您需要将这些其他查找列添加到单独的表中索引,这样就不必尝试协调多个索引。
答案 1 :(得分:0)
如果这是子查询,则可以在wfapplication和wfprocessingstancelog之间进行内部联接。没有充分的理由为此使用子查询:
SELECT WFApplication.*,
WorkflowIncidentType.TypeName ProcessCategory,
WFProcess.WFProcessName ProcessName,
LUTAppStatus.EnglishName AppStatus
FROM WFApplication
Inner Join WFProcessInstanceLog WPL on WPL.ProcessID = WFApplicaiton.ProcessId
INNER JOIN LUTAppStatus ON WFApplication.ApplicationStatus = LUTAppStatus.Id
INNER JOIN WorkflowIncidentType ON WorkflowIncidentType.TypeID = WFApplication.ApplicationIncidentType
INNER JOIN WFProcess ON WFProcess.WFProcessId = WFApplication.ApplicationProcess
LEFT OUTER JOIN IBSCustomer ON IBSCustomer.RIM = WFApplication.RIM
LEFT OUTER JOIN Reschedule ON Reschedule.RescheduleId = WFApplication.ProcessId
WHERE WFProcessInstanceId IN (28251,
28345,
28773,
28774,
28846,
29309, .....)