Sql server SQL Server 2008中的T-SQL-复杂的连接条件或单独查询的并集
这是一个执行速度问题 下面有两个表格示例。主表和明细表。main的主键在detail表中的两个不同外键列上被引用。决策基于主表的状态列 有关于任务表和任务数据表。Taskdet表有两个对任务表主键的引用。任务表主键根据任务类型在taskdet表外键列之一中引用,如下所示:Sql server SQL Server 2008中的T-SQL-复杂的连接条件或单独查询的并集,sql-server,database,join,Sql Server,Database,Join,这是一个执行速度问题 下面有两个表格示例。主表和明细表。main的主键在detail表中的两个不同外键列上被引用。决策基于主表的状态列 有关于任务表和任务数据表。Taskdet表有两个对任务表主键的引用。任务表主键根据任务类型在taskdet表外键列之一中引用,如下所示: iType=0 --> Original task with or without modifications TaskDet.MainTskFk=Task.TaskID iType=1 --&
iType=0 --> Original task with or without modifications
TaskDet.MainTskFk=Task.TaskID
iType=1 --> Task unchanged and assigned
TaskDet.MainTskFk=Task.TaskID
iType=2 --> Change on original task
TaskDet.ModiTskFk=Task.TaskID
Additionally detail table has a pointer to original task that gets modified
TaskDet.MainTskFk=Task.TaskID of task table entry where its itype=0
iType=3 --> Original Task completed
TaskDet.ModiTskFk=Task.TaskID
查询以获得原始任务的Completed和修改person PartnerFk字段的task可以通过两种方式完成。使用带复杂条件的内部联接-SQL 1-或查询task和detail表缠绕并合并结果-SQL 2-
这两种方法都适用于少量数据,但当应用于任务表中有560k条目的数据库和任务详细信息表中有250k条目的数据库时,SLQ 1无法运行。我认为查询同一个表两次要比在单个查询中连接表和使用SQL 1中的连接条件慢
与构造复杂联接相比,两次查询同一个表的性能何时会有所提高
SQL 1:
SELECT
Task.TaskID
,Task.dtFrom
,Task.dtTo
,Case Task.itype When 2 Then TaskDet.MainTskFk When Else 0 END As ModfierOfTaskID
,TaskDet.ItemDesc
,TaskDet.EstimatedTime
FROM
Task
INNER JOIN
TaskDet ON (Task.iType =3 and Task.TaskID = TaskDet.MainTskFK)
OR (Task.iType =2 and Task.TaskID = TaskDet.ModiTskFK)
WHERE
Task.PartnerFK = 1
SQL 2:
SELECT
Task.TaskID
,Task.dtFrom
,Task.dtTo
,0 As ModfierOfTaskID
,TaskDet.ItemDesc
,TaskDet.EstimatedTime
FROM
Task
INNER JOIN
TaskDet ON (Task.iType = 3 and Task.TaskID = TaskDet.MainTskFK)
WHERE
Task.PartnerFK = 1
UNION ALL
SELECT
Task.TaskID
,Task.dtFrom
,Task.dtTo
,TaskDet.MainTskFk As ModfierOfTaskID
,TaskDet.ItemDesc
,TaskDet.EstimatedTime
FROM
Task
INNER JOIN
TaskDet ON (Task.iType =2 and Task.TaskID = TaskDet.ModiTskFK)
WHERE
Task.PartnerFK = 1
表结构和数据:
任务表的主键为TaskID
任务表:
任务数据表:
复杂联接条件的问题在于,它可能使SQL Server无法使用索引进行联接,它可能会导致数据溢出到tempdb,因为数据不适合内存,或者需要额外的排序,因为数据不再在聚集索引上联接,或者发生其他一些昂贵的操作 对于这种特殊情况,您可能会通过比较两种情况下的实际执行计划和打开统计io时显示的i/o量来很容易地找到答案
TaskID dtFrom dtTo Notes PartnerFK iType
-----------------------------------------------------------------------------------------------------
1 01-01-2014 20-03-2014 Original Task Requires modification 1 0
2 18-02-2014 20-04-2014 Assigned task and unchanged 4 1
3 28-01-2014 18-02-2014 Original Task assiged not started unchanged 4 0
4 02-04-2014 05-05-2014 Changes required on assigned task 1 2
5 31-12-2013 01-04-2014 Assigned task and unchanged 2 1
6 12-03-2014 24-03-2014 Original task completed 1 3
-----------------------------------------------------------------------------------------------------
DetID MainTskFK ModiTskFK Itemdesc EstimatedTime
-----------------------------------------------------------------------------------------------------
1 1 Prepare end of month letter 200
2 1 Reconcile bank statements 150
3 2 tsk1 200
4 2 tsk2 150
5 5 Conclude lease agreement 25
6 5 Get sales figures as EOM 100
7 5 Glass cleaning 35
8 6 Prepare car exhibition 500
9 6 Conclude exhibition lease agreements 85
10 1 4 Requires additional Time 50
-----------------------------------------------------------------------------------------------------