我是否应该修改一些关于以下查询的内容(因为15 seconds
需要很长时间!!只是为了带来400
条记录
select unique a.regnum , a.name
from re23mmf a , rj82std b , gg7crs c , rr099stdusr j , hkcourse h , aalt:mms3f x , aalt:rhcasestudy y
where a.regnum = b.regnum and a.regnum = c.regnum
and b.term_no = ( select max(d.term_no) from rj82std d where d.regnum = a.regnum )
and b.dep_code = j.dep_code and b.study_code = j.study_code
and j.start_date <=today and j.end_date >=today
and j.emp_num =4324
and c.crsnum = h.crsnum
and h.is_project = 'j'
and a.regnum = x.regnum and x.regserial = y.regserial
and y.batch_no = ( select max(z.batch_no) from rhcasestudy z where z.regserial = y.regserial )
and y.case_code <> 5
请在编写这样的查询时,关于性能问题,我应该注意什么?
答案 0 :(得分:3)
首先检查索引。您是否在表上有聚簇索引或非聚簇索引?您可以使用查询中的列创建非聚集索引,以提高性能。
答案 1 :(得分:3)
使用JOIN表示法,您可以写:
SELECT UNIQUE a.regnum, a.name
FROM re23mmf a
JOIN rj82std b ON a.regnum = b.regnum
JOIN gg7crs c ON a.regnum = c.regnum
JOIN rr099stdusr j ON b.dep_code = j.dep_code
AND b.study_code = j.study_code
JOIN hkcourse h ON c.crsnum = h.crsnum
JOIN aalt:mms3f x ON a.regnum = x.regnum
JOIN aalt:rhcasestudy y ON x.regserial = y.regserial
WHERE b.term_no = (SELECT MAX(d.term_no) FROM rj82std d
WHERE d.regnum = a.regnum)
AND j.start_date <= TODAY AND j.end_date >= TODAY
AND j.emp_num = 4324
AND h.is_project = 'j'
AND y.batch_no = (SELECT MAX(z.batch_no) FROM rhcasestudy z
WHERE z.regserial = y.regserial)
AND y.case_code <> 5
除非我在转录和编辑期间进行了翻身,否则这与原始查询实际上是相同的。我在WHERE子句中留下了单表过滤条件;优化器应将它们推送到相关表中,以便最大限度地减少工作量。
如前所述,关键是研究SET EXPLAIN的输出并确保没有丢失的索引。确保统计数据是最新的也是一个好主意,可能使用AUS(自动更新统计数据)。
有助于确定表格的基数。在15秒内生成400行可能是可怕的性能(在任何表中最多有400行),或者它可能是出色的性能(最大的表有40亿行,每行2 KiB)。如果没有调整信息的大小,很难知道哪个更有可能。
a ----> b ----> j
| |
| +-----> d
|
+-----> c ----> h
|
+-----> x ----> y ----> z
该图显示了连接结构。别名a
独立地加入b
,c
和x
; b
加入j
和d
上的(查询); c
与h
加入; x
与y
加入;和y
加入(z
上的子查询。
请注意,子查询都是相关的子查询;总的来说,这些效率较低。也许您需要使用以下子查询:
SELECT d.regnum, MAX(d.term_no) AS max_term_no
FROM rj82std AS d
GROUP BY d.regnum
FROM子句中的:
SELECT UNIQUE a.regnum, a.name
FROM re23mmf a
JOIN rj82std b ON a.regnum = b.regnum
JOIN gg7crs c ON a.regnum = c.regnum
JOIN rr099stdusr j ON b.dep_code = j.dep_code
AND b.study_code = j.study_code
JOIN hkcourse h ON c.crsnum = h.crsnum
JOIN aalt:mms3f x ON a.regnum = x.regnum
JOIN aalt:rhcasestudy y ON x.regserial = y.regserial
JOIN (SELECT d.regnum, MAX(d.term_no) AS max_term_no
FROM rj82std AS d
GROUP BY d.regnum
) AS d1 ON b.regnum = d1.regnum AND b.term_no = d1.max_term_no
JOIN (SELECT z.regserial, MAX(z.batch_no) AS max_batch_no
FROM rhcasestudy z
GROUP BY z.regserial
) AS z1 ON y.regserial = z1.regserial
AND y.batch_no = z1.max_batch_no
WHERE j.start_date <= TODAY AND j.end_date >= TODAY
AND j.emp_num = 4324
AND h.is_project = 'j'
AND y.case_code <> 5
这些子查询只需要评估一次,而不是像相关子查询中那样对每一行进行评估。这不是一个有保证的胜利,但它通常会有很大的帮助。
答案 2 :(得分:1)