oracle查询的查询优化
Posted
技术标签:
【中文标题】oracle查询的查询优化【英文标题】:Query optimization of oracle query 【发布时间】:2018-10-11 19:35:06 【问题描述】:我对查询优化知之甚少,在这里我需要一些帮助。这是我们项目的示例代码,它长期运行的 oracle 查询从 2 个不同的表(student、student_info)中提取数据。
是否有可能对此进行优化? where
子句“和”操作在这里如何工作?
在执行 AND 子句时它是否保持任何顺序?下面的查询如何通过删除行 b.student_id in ('a123','b123','c123')
的代码使之前和之后有所不同。
我们无权在该表列上添加索引。
我们如何在不创建索引的情况下提高性能。
select a.student_id
max(decode(a.marks_limit, 99.99,100,null )) as max_marks,
b.student_city_code "NYC",
from student a,
student_info b
where a.student_id=b.student_id
and a.student_id in ('a123','b123','c123')
and b.student_id in ('a123','b123','c123')
and b.adress_modified > TO_TIMESTAMP('2003/12/13 10:13:18', 'YYYY/MM/DD HH:MI:SS')
group by a.student_id, b.student_city_code;
【问题讨论】:
用您真正使用的数据库标记您的问题。 SQL Server 还是 Oracle??哪一个?student
中有多少条记录? student_info
有多少人?
【参考方案1】:
你可以:
select a.student_id
max(decode(a.marks_limit, 99.99,100,null )) as max_marks,
b.student_city_code "NYC",
from student a
join student_info b
on a.student_id=b.student_id -- explicit join
where a.student_id in ('a123','b123','c123') -- removing duplicate condition
and b.adress_modified>TO_TIMESTAMP('2003/12/13 10:13:18','YYYY/MM/DD HH:MI:SS')
group by a.student_id, b.student_city_code;
并添加索引:
CREATE INDEX id1 ON student(student_id);
CREATE INDEX id2 ON student_info(student_id);
CREATE INDEX id3 ON student_info(adress_modified);
【讨论】:
它的远程数据库,我们无权在该表列上添加索引。谢谢 join操作对查询的执行时间有影响吗? @user1272269 显式 JOIN 优于逗号语法(没有性能提升) @user1272269 - 当您说 “其远程数据库” 时,您的意思是它是另一个数据库,并且您正在通过数据库链接查询本地数据库吗?或者这只是误用?清晰度至关重要,因为调整分布式事务与调整一个数据库中的查询非常不同。【参考方案2】:只是一些建议。
你已经有了 a.student_id=b.student_id 所以 ('a123,'b123','c123') 中的条件 b.student_id 只是一个有用的重复 您还应该使用基于 where 子句的显式连接表示法而不是旧的隐式表示法
select a.student_id
max(decode(a.marks_limit, 99.99,100,null )) as max_marks,
b.student_city_code "NYC",
from student a
INNER JOIN student_info b ON a.student_id= b.student_id
WHERE
and a.student_id in ('a123','b123','c123')
and b.adress_modified > TO_TIMESTAMP('2003/12/13 10:13:18', 'YYYY/MM/DD HH:MI:SS')
group by a.student_id, b.student_city_code
为了获得更好的性能,您应该检查表上的复合索引
student_info ( adress_modified, student_id )
或
student_info ( adress_modified, student_id, student_city_code )
【讨论】:
" 条件 b.student_id in ('a123,'b123','c123') 只是一个有用的重复“这对查询的性能(执行时间)有什么影响吗? join操作对查询的执行时间有影响吗? 试着让我知道.. ..在我的回答中,这些主要是建议..(无论如何,如果查询优化器以聪明的方式工作不应该有所作为..)..但正如建议的那样条件是多余且令人困惑的 对于 JOIN ..no .. old where 子句 sintax 或 INNER JOIN 子句 sintax 对于性能是相同的 .. .. 性能主要与索引有关.. 所以你应该使用基于最有选择性的列从左到右和最后一列不涉及 where 但在 select 中使用【参考方案3】:首先,使用正确、明确、正确 JOIN
语法以及合理的表别名和case
表达式编写查询。
修好之后,我希望是这样的:
select s.student_id
max(s.marks_limit) as max_marks, -- I have no idea what the decode() is supposed to be doing
si.student_city_code
from student s join
student_info si
on s.student_id = si.student_id
where s.student_id in ('a123', 'b123', 'c123')
and si.adress_modified > TIMESTAMP '2003-12-13T10:13:18'HH:MI:SS')
group by s.student_id, si.student_city_code;
我将从student(student_id)
和student_info(student_id address_modified, student_city_code)
的索引开始。
【讨论】:
join操作对查询的执行时间有影响吗? @user1272269 。 . .不,它在理解查询方面有所不同。另外,这就像使用现代英语与莎士比亚英语一样。JOIN
是在表之间明确表达JOIN
s 的正确方式。以上是关于oracle查询的查询优化的主要内容,如果未能解决你的问题,请参考以下文章