这是有问题的遗留代码。 #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.
命令已完成且未返回任何结果
答案 0 :(得分:0)
听起来像#elig_patients是与永久表相比的少量记录,所以你想要的是用所有其他表的索引连接对其进行扫描。
为此,您需要2个患者表上的患者ID和站点表上的site_id的索引。
如果存在我不想的那些,你就不会有重新格式和/或表格。
更改查询计划可能是过时的统计信息。
您是否定期对表格进行REORG,并更新统计信息吗?如果这是Sybase 15,则UPDATE INDEX STATISTICS更好(参见文档,如果需要节省,请参阅DATACHANGE。)
答案 1 :(得分:0)
再次感谢您的意见。这是在存储过程中。该表在proc中创建并删除。