为REFORMATTING创建的Sybase工作表 - 正常完成(执行< 1min),有时是表扫描(8hrs),为什么?

时间:2014-05-07 23:17:04

标签: sybase optimization

这是有问题的遗留代码。 #elig_patients有~100k recs,没有索引。所有表格增长都很慢。这个问题(执行时间为7-8小时)一年前开始非常偶然。它现在每隔3或4晚发生一次(在cron上运行。服务器上没有其他工作。我偶尔也无法重现这个问题)。为什么优化器决定在出现问题时不为#elig_patients创建工作表?

    INSERT INTO #PatientData(patient_id, study_site_no, study_pat_id, mode)
    SELECT DISTINCT p.patient_id, s.study_site_no, p.study_pat_id, "sq"
      FROM study_site s, patient p, patient_visit pv, #elig_patients e
     WHERE s.site_id = p.site_id
       AND p.patient_id = pv.patient_id
       AND pv.patient_id = e.patient_id
       AND accept_status = 1
       AND image_status = 1
       AND label_status = 1
       AND ISNULL(sq_status,0) = 0
       AND ISNULL(review_flag,0) = 0

当事情进展顺利时,这是执行计划

陈述9的查询计划(第77行)。

STEP 1
    The type of query is INSERT.
    The update mode is direct.
    Worktable2 created for REFORMATTING.

    FROM TABLE
        study_site
        s
    Nested iteration.
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 2 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.
    TO TABLE
        Worktable2.

STEP 2
    The type of query is INSERT.
    The update mode is direct.
    Worktable3 created for REFORMATTING.

    FROM TABLE
        #elig_patients
        e
    Nested iteration.
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 2 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.
    TO TABLE
        Worktable3.

STEP 3
    The type of query is INSERT.
    The update mode is direct.
    Worktable1 created, in allpages locking mode, for DISTINCT.

    FROM TABLE
        patient
        p
    Nested iteration.
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 2 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.

    FROM TABLE
        Worktable2.
    Nested iteration.
    Using Clustered Index.
    Forward scan.
    Positioning by key.
    Using I/O Size 2 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.

    FROM TABLE
        patient_visit
        pv
    Nested iteration.
    Using Clustered Index.
    Index : pv_ind
    Forward scan.
    Positioning by key.
    Keys are:
        patient_id ASC
    Using I/O Size 2 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.

    FROM TABLE
        Worktable3.
    EXISTS TABLE : nested iteration.
    Using Clustered Index.
    Forward scan.
    Positioning by key.
    Using I/O Size 2 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.
    TO TABLE
        Worktable1.

STEP 4
    The type of query is INSERT.
    The update mode is direct.
    This step involves sorting.

    FROM TABLE
        Worktable1.
    Using GETSORTED
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 2 Kbytes for data pages.
    With MRU Buffer Replacement Strategy for data pages.
    TO TABLE
        #PatientData
    Using I/O Size 2 Kbytes for data pages.

请注意,有4个步骤。 在第2步:为重新格式化创建的工作表3。在步骤3中,该表上的聚集索引用于JOIN。

以下是代码执行数小时的执行计划。请注意,有3个步骤,并且没有使用工作表来重新构建#elig_patients表。

陈述9的查询计划(第77行)。

STEP 1
    The type of query is INSERT.
    The update mode is direct.
    Worktable2 created for REFORMATTING.

    FROM TABLE
        study_site
        s
    Nested iteration.
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 16 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.
    TO TABLE
        Worktable2.

STEP 2
    The type of query is INSERT.
    The update mode is direct.
    Worktable1 created, in allpages locking mode, for DISTINCT.

    FROM TABLE
        #elig_patients
        e
    Nested iteration.
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 2 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.

    FROM TABLE
        patient
        p
    Nested iteration.
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 16 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.

    FROM TABLE
        Worktable2.
    Nested iteration.
    Using Clustered Index.
    Forward scan.
    Positioning by key.
    Using I/O Size 16 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.

    FROM TABLE
        patient_visit
        pv
    EXISTS TABLE : nested iteration.
    Using Clustered Index.
    Index : pv_ind
    Forward scan.
    Positioning by key.
    Keys are:
        patient_id ASC
    Using I/O Size 16 Kbytes for data pages.
    With LRU Buffer Replacement Strategy for data pages.
    TO TABLE
        Worktable1.

STEP 3
    The type of query is INSERT.
    The update mode is direct.
    This step involves sorting.

    FROM TABLE
        Worktable1.
    Using GETSORTED
    Table Scan.
    Forward scan.
    Positioning at start of table.
    Using I/O Size 16 Kbytes for data pages.
    With MRU Buffer Replacement Strategy for data pages.
    TO TABLE
        #PatientData
    Using I/O Size 2 Kbytes for data pages.

命令已完成且未返回任何结果

2 个答案:

答案 0 :(得分:0)

听起来像#elig_patients是与永久表相比的少量记录,所以你想要的是用所有其他表的索引连接对其进行扫描。

为此,您需要2个患者表上的患者ID和站点表上的site_id的索引。

如果存在我不想的那些,你就不会有重新格式和/或表格。

更改查询计划可能是过时的统计信息。

您是否定期对表格进行REORG,并更新统计信息吗?如果这是Sybase 15,则UPDATE INDEX STATISTICS更好(参见文档,如果需要节省,请参阅DATACHANGE。)

答案 1 :(得分:0)

再次感谢您的意见。这是在存储过程中。该表在proc中创建并删除。