用作视图时,查询不使用索引

时间:2017-05-28 14:55:52

标签: sql oracle optimization oracle11g

我写了一个查询,当在多个值上执行时 - 使用表的索引并快速返回结果。

当我使用完全相同的语法创建视图时,索引有时会保持未使用状态。

例如:查询以下查询时,使用索引DEP_IDX,查询需要几秒钟才能返回结果:

Select /*+INDEX (s DEP_IDX) */ department, avg(salary) as dep_avg
From salaries s
Where department in (1,4,7,8)
Group by department

当我使用相同的语法创建视图时,如下所示:

Create or replace view Departments_Avg_Salary as
  Select /*+INDEX (s DEP_IDX)*/ department, avg(salary) as dep_avg
  From salaries s
  Group by department

然后在查询中使用该视图:

Select e.Employee_Name, e.Employee_Salary, d.dep_avg
From Employees​ e Left join
     Departments_Avg_Salary d
     On d.department = e.Employees_Department
Where e.Employee_Name in ('Michael', 'Nittai', 'Jack')

不使用索引,查询需要生命周期才能返回!

如您所见,使用INDEX提示没有任何区别......

事实证明,鉴于表格的巨大规模,没有使用表格访问存储完全的方案将是有效的方式,所以我真的在寻找一种强制数据库使用索引的解决方案

有什么想法吗?

提前致谢。

2 个答案:

答案 0 :(得分:1)

你可能最好写这样的查询:

Select e.Employee_Name, e.Employee_Salary,
       (select avg(s.salary)
        from salaries s
        where s.department = e.Employees_Department
       ) avg_salary
From Employees​ e 
Where e.Employee_Name in ('Michael', 'Nittai', 'Jack');

然后在employees(Employee_name)salaries(department, salary)上建立索引。

原始查询中的索引可能用于WHERE子句,而不是GROUP BY。至于视图中的提示,我将从documentation

中的警告开始
  

Oracle不鼓励在视图内部或视图上使用提示(或者   子查询)。这是因为您可以在一个上下文中定义视图   在另一个中使用它们。此外,此类提示可能会导致意外   执行计划。特别是,视图内部或视图中的提示是   处理方式不同,具体取决于视图是否可以合并到   顶级查询。

答案 1 :(得分:0)

您的独立查询包含此WHERE子句:

Where department in (1,4,7,8)

因此,使用索引检索几个部门的记录会很有效。

您的视图不会按部门过滤,因此它将执行全表扫描。您希望使用视图的查询将department谓词推送到视图的查询...

From Employees​ e Left join
     Departments_Avg_Salary d
     On d.department = e.Employees_Department

...但是唉,优化器不能像那样工作