Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用子查询和联接的SQL查询性能_Sql_Sql Server - Fatal编程技术网

使用子查询和联接的SQL查询性能

使用子查询和联接的SQL查询性能,sql,sql-server,Sql,Sql Server,我需要加快以下查询的执行时间,因为执行时间太长,我认为子查询就是问题所在 SELECT WFApplication.*, WorkflowIncidentType.TypeName ProcessCategory, WFProcess.WFProcessName ProcessName, LUTAppStatus.EnglishName AppStatus FROM WFApplication INNER JOIN LUTAppStatus ON WFA

我需要加快以下查询的执行时间,因为执行时间太长,我认为子查询就是问题所在

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, .....) 

如果是子查询,则可以在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, .....) 

如果是子查询,则可以在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, .....) 

好的,下面是SQL查询性能优化的基础知识

第一步:显示实际执行计划。在“查询”菜单中,选中“包括实际执行计划”。然后,当您运行查询时,结果窗格中将显示一个额外的选项卡,用于“执行计划”

第二步:查看树中最右边的节点。通常有四种可能性:

  • 表格扫描。基本上,这是不好的。这意味着必须查看整个表才能找到它要查找的内容-根本没有使用索引。如果桌子很小,那可能没什么大不了的;如果桌子很大,你可能会遇到问题
  • 聚集索引扫描。也不好。聚集索引是表,因此,如果SQL扫描一个表,则意味着它扫描整个表
  • 索引扫描-非聚集。半坏。基本上,它能够使用索引来帮助查找数据(比完整的表更好),但无法使用二进制查找来快速缩小所查找的数据范围
  • 索引搜索(非聚集或聚集)-您的目标。这意味着SQL能够快速找到它所寻找的数据的二进制方式
现在,是什么导致SQL选择一个选项而不是另一个?第一件大事是你的索引。通常,“执行计划”会提醒您缺少可以提高查询性能的索引。但你可以手动查看-如果它是通过“表A”使用完整扫描。。。为什么?它在查找、搜索或匹配哪个列?很可能,该列需要有一个索引,以便引擎能够快速匹配它

但还有其他原因。假设该表没有那么大,并且您将许多条目与该表进行匹配。SQL只查看整个表可能会更快

另一个经常被忽略的原因是:在相关列上有索引,但它们没有足够的缩小数据范围以使其有价值——或者,它正在查看太多不同的索引,因此试图将它们全部与原始表进行比较要比仅使用大表慢。如果是这种情况,解决方案是在索引中创建具有多个列的索引

诊断此类问题的一个好方法是省略一些表/数据,并查看执行计划是否更改。例如,请尝试以下查询:

SELECT WFApplication.*
FROM WFApplication
WHERE WFProcessInstanceId IN (28251,
                          28345,
                          28773,
                          28774,
                          28846,
                          29309, .....)
执行计划有变化吗?如果上面语句中的计划不好,则可能意味着您缺少WFProcessInstanceId上的索引,或者您的表不够大,无法对主表进行5000次引用


但是,如果它在该查询上使用索引查找,但在添加其他表时切换到扫描操作,则可能表明您需要将这些额外的查找列添加到单独的索引中,这样它就不必尝试协调多个索引。

好的,下面是SQL查询性能优化的基础知识

第一步:显示实际执行计划。在“查询”菜单中,选中“包括实际执行计划”。然后,当您运行查询时,结果窗格中将显示一个额外的选项卡,用于“执行计划”

第二步:查看树中最右边的节点。通常有四种可能性:

  • 表格扫描。基本上,这是不好的。这意味着必须查看整个表才能找到它要查找的内容-根本没有使用索引。如果桌子很小,那可能没什么大不了的;如果桌子很大,你可能会遇到问题
  • 聚集索引扫描。也不好。聚集索引是表,因此,如果SQL扫描一个表,则意味着它扫描整个表
  • 索引扫描-非聚集。半坏。基本上,它能够使用索引来帮助查找数据(比完整的表更好),但无法使用二进制查找来快速缩小所查找的数据范围
  • 索引搜索(非聚集或聚集)-您的目标。这意味着SQL能够快速找到它所寻找的数据的二进制方式
现在,是什么导致SQL选择一个选项而不是另一个?第一件大事是你的索引。通常,“执行计划”会提醒您缺少可以提高查询性能的索引。但你可以手动查看-如果它是通过“表A”使用完整扫描。。。为什么?它在查找、搜索或匹配哪个列?很可能,该列需要有一个索引,以便引擎能够快速匹配它

但还有其他原因。假设该表没有那么大,并且您将许多条目与该表进行匹配。SQL只查看整个表可能会更快

另一个经常被忽略的原因是:在相关列上有索引,但它们没有足够的缩小数据范围以使其有价值——或者,它正在查看太多不同的索引,因此试图将它们全部与原始表进行比较要比仅使用大表慢。如果是这种情况,解决方案是在索引中创建具有多个列的索引

诊断此类问题的一个好方法是省略一些tabl