【问题标题】:T-SQL in SQL Server 2008 - complex joining conditions or union of separate queriesSQL Server 2008 中的 T-SQL - 复杂的连接条件或单独查询的联合
【发布时间】:2015-02-08 15:16:57
【问题描述】:

这是一个执行速度问题。

有两个表(示例如下)。主表和明细表。主键的主键在两个不同外键列的详细表中引用。该决定基于主表的状态列。

关于任务表和taskdet表。 Taskdet 表有两个对 Task 表主键的引用。任务表主键根据任务类型在 taskdet 表外键列之一中引用,如下所示:

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

完成原始任务的查询和对人员任务(PartnerFk 字段)的修改可以通过两种方式完成。使用具有复杂条件的内连接 - SQL 1 - 或查询任务和详细信息表缠绕并联合结果 - 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

表结构和数据:

Task 表以TaskID 作为其主键

Task表:

    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
    -----------------------------------------------------------------------------------------------------

TaskDet表:

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
-----------------------------------------------------------------------------------------------------

【问题讨论】:

    标签: sql-server database join


    【解决方案1】:

    复杂连接条件的问题在于它可能使 SQL Server 无法使用索引进行连接,它可能导致 tempdb 溢出,因为数据不适合内存或需要额外的排序,因为数据不再加入聚簇索引(或发生其他一些昂贵的操作)。

    对于这种特殊情况,您可能很容易通过比较实际执行计划和两种情况下打开“statistics io”时显示的 i/o 数量来计算出来。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 2017-09-30
      相关资源
      最近更新 更多