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 是在表之间明确表达JOINs 的正确方式。

以上是关于oracle查询的查询优化的主要内容,如果未能解决你的问题,请参考以下文章

Oracle查询速度优化问题

oracle查询的查询优化

求助oracle like%.%模糊查询优化

Oracle - 查询优化 - 查询运行时间长

oracle查询优化之子查询条件优化

求助Oracle大表查询优化