假设有三列ename , city , salary
。此表中有数百万行名为emp
。
ename city salary
ak newyork $5000
bk abcd $4000
ck Delhi $4000
....................
...................
Maverick newyork $8000
我想检索名称与city
相同Maverick
的所有员工。
select * from emp where
city = (select city from emp where ename= 'maverick' )
我知道它会起作用,但出于性能原因,此查询不好,因为此查询中存在两个where
子句。
我需要一个比上述查询具有更好性能的查询。
答案 0 :(得分:1)
这会给你相同的输出,但我怀疑它会有更好的表现。
你可以比较一下这些计划。
select x.*
from emp x
join (select city from emp where ename = 'maverick') y
on x.city = y.city
您还可以添加2个索引,一个在ENAME列上,另一个在CITY列上。
create index emp_idx_ename on emp(ename);
create index emp_idx_city on emp(city);
第一个索引将加速其结果正在加入的内联视图,因为它正在搜索员工的表格。
第二个索引将加速父查询,因为它正在搜索表中的给定城市。
您可以像其他人建议的那样在emp(city,ename)上创建一个复合索引,因为您只选择了ename为X的city列,允许内联视图中的查询仅使用索引和不是表,我最初没有想到的。它可能会提供额外的提升,或多或少,取决于表的大小,虽然索引也会更大。
为了确保索引会立即使用与该表相关的更新统计信息,我还会在您创建上述索引后运行以下命令,以便您的查询立即开始使用它们:
analyze table emp compute statistics;
答案 1 :(得分:1)
Oracle可能会很好地为此查询获取最佳执行计划:
select *
from emp
where city = (select city from emp where ename= 'maverick' ) ;
有助于查询的是两个索引:
create index idx_emp_ename_city on emp(ename, city)
create index idx_emp_ename_city on emp(city)
第一个将用于子查询。第二个查找所有匹配的行。如果没有索引,Oracle将不得不至少读取一次表(我认为至少两次),这将影响这么大的表上的性能。
答案 2 :(得分:0)
有时复杂性会因为进一步缩小查询范围而获胜。只是无法进一步优化此查询。
您可以选择添加索引以创建更好的效果。该索引应该出现在city
和ename
。
尝试使用此方法创建这些索引:
create index emp_city -- for the outer where clause
on emp
( city
)
create index emp_ename_city -- for the sub query
on emp
( ename
, city
)
答案 3 :(得分:0)
您可以使用with
声明...用户建议您使用多个部门
WITH new_city_tab AS (
SELECT city AS ncity
FROM emp WHERE ename='Maverick'
GROUP BY city)
SELECT *
FROM emp e,
new_city_tab c
WHERE E.city = c.ncity;