简体   繁体   English

使用查询提示在内部表中使用索引

[英]Using query hints to use a index in an inner table

I have a query which uses the view a as follows and the query is extremely slow.我有一个查询,它使用如下视图 a 并且查询非常慢。

select *
from a
where a.id = 1 and a.name = 'Ann';

The view a is made up another four views b,c,d,e.视图 a 由另外四个视图 b,c,d,e 组成。

select b.id, c.name, c.age, e.town
from b,c,d,e
where c.name = b.name AND c.id = d.id AND d.name = e.name;

I have created an index on the table of c named c_test and I need to use it when executing the first query.我在 c 的表上创建了一个名为 c_test 的索引,我需要在执行第一个查询时使用它。

Is this possible?这可能吗?

Are you really using this deprecated 1980s join syntax?您真的在使用这种已弃用的 1980 年代连接语法吗? You shouldn't.你不应该。 Use proper explicit joins ( INNER JOIN in your case).使用正确的显式连接(在您的情况下为INNER JOIN )。

You are joining the two tables C and D on their IDs.您正在加入两个表 C 和 D 的 ID。 That should mean they are 1:1 related.这应该意味着它们是 1:1 相关的。 If not, "ID" is a misnomer, because an ID is supposed to identify a row.如果不是,“ID”是用词不当,因为 ID 应该标识一行。

Now let's look at the access route: You have the ID from table B and the name from tables B and C.现在让我们看看访问路径:您有来自表 B 的 ID 和来自表 B 和 C 的名称。 We can tell from the column name that b.id is unique and Oracle guarantees this with a unique index, if the database is set up properly.我们可以从列名中看出 b.id 是唯一的,如果数据库设置正确,Oracle 可以通过唯一索引保证这一点。

This means the DBMS will look for the B row with ID 1, find it instantly in the index, find the row instantly in the table, see the name and see whether it matches 'Ann'.这意味着 DBMS 将查找 ID 为 1 的 B 行,立即在索引中找到它,立即在表中找到该行,查看名称并查看它是否与“Ann”匹配。

The only thing that can be slow hence is joining C, D, and E. Joining on unique IDs is extremely fast.因此,唯一可能会变慢的是加入 C、D 和 E。加入唯一 ID 非常快。 Joining on (non-unigue?) names is only fast, if you provide indexes on the names.如果您在名称上提供索引,则加入(非唯一?)名称只会很快。 I'd recommend the following indexes accordingly:我会相应地推荐以下索引:

create index idx_c on c (name);
create index idx_e on e (name);

To get this faster still, use covering indexes instead:为了更快地做到这一点,请改用覆盖索引:

create index idx_b on b (id, name);
create index idx_c on c (name, id, age);
create index idx_d on d (id, name);
create index idx_e on e (name, town);

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

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