简体   繁体   English

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

[英]Query does not use index when used as a view

I wrote a query that when executed on several values - uses the table's index and returns results quickly. 我编写了一个查询,该查询对多个值执行时-使用表的索引并快速返回结果。

When I created a view using the very same syntax, the index sometimes remain unused. 当我使用相同的语法创建视图时,索引有时保持未使用状态。

For example: when querying the following query, the index DEP_IDX is used, and the query takes a few seconds to return results: 例如:查询以下查询时,使用索引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

When I create a view using the same syntax, like this: 当我使用相同的语法创建视图时,如下所示:

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

And then use the view in a query: 然后在查询中使用视图:

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')

The Index is not used and the query takes a lifetime to return! 不使用索引,查询需要一生才能返回!

As you can see, using the INDEX hint made no difference... 如您所见,使用INDEX提示没有区别...

As it turns out, given the table's​ huge size, there will be no scenario in which using table access storage full will be the efficient way, so I am really looking for a solution that will force the DB to use the index. 事实证明,鉴于表的巨大容量,在任何情况下都不会出现充分使用表访问存储的情况,因此我确实在寻找一种解决方案,以强制DB使用索引。

Any ideas? 有任何想法吗?

Thanks in advance. 提前致谢。

You are probably best off writing the query like this: 您最好是这样编写查询:

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');

And then having indexes on employees(Employee_name) and salaries(department, salary) . 然后具有有关employees(Employee_name)salaries(department, salary)索引。

The index in your original query is probably being used for the WHERE clause, not the GROUP BY . 您原始查询中的索引可能用于WHERE子句,而不是GROUP BY As for hints in views, I would start with the warning in the documentation : 至于视图中的提示,我将从文档中的警告开始:

Oracle does not encourage the use of hints inside or on views (or subqueries). Oracle不鼓励在视图(或子查询)内部或之上使用提示。 This is because you can define views in one context and use them in another. 这是因为您可以在一个上下文中定义视图,而在另一个上下文中使用它们。 Also, such hints can result in unexpected execution plans. 同样,这样的提示可能导致意外的执行计划。 In particular, hints inside views or on views are handled differently, depending on whether the view is mergeable into the top-level query. 特别是,根据视图是否可合并到顶级查询中,对视图内部或视图上的提示的处理方式有所不同。

Your standalone query includes this WHERE clause: 您的独立查询包含以下WHERE子句:

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

So it would be efficient to use an index to retrieve records for a few departments. 因此,使用索引检索几个部门的记录将非常有效。

Your view does not filter on by department so it's going to execute a Full Table Scan. 您的视图不会按部门进行筛选,因此将执行全表扫描。 What you're hoping is that the query using the view is going to push the department predicate into the view's query ... 您希望使用该视图的查询将把department谓词推入该视图的查询中...

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

... but alas the optimizer doesn't work like that ...但是可惜优化器无法那样工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM