如果您正在寻找一行的存在,而不是它出现的次数,那么这会更合适:
SELECT 1
FROM DB.TABLE
WHERE ColumnA = 'VALUE'
AND ROWNUM = 1
一旦找到一行,它将尽快停止查询;但是,如果您需要它更快,这就是索引的用途。
测试用例:
create table q8806566
( id number not null,
column_a number not null,
padding char(256), -- so all the rows aren't really short
constraint pk_q8806566 primary key (id)
using index tablespace users
)
tablespace users;
insert into q8806566 -- 4 million rows
(id, column_a, padding)
with generator as
(select --+ materialize
rownum as rn from dba_objects
where rownum <= 2000)
select rownum as id, mod(rownum, 20) as column_a,
v1.rn as padding
from generator v1
cross join generator v2;
commit;
exec dbms_stats.gather_table_stats (ownname => user, tabname => 'q8806566');
column_A 的数据分布良好,可以在所有值的前几个块中找到,因此该查询运行良好:
SELECT 1
FROM q8806566
WHERE Column_A = 1
AND ROWNUM = 1;
不到 0.1 秒的执行时间和低 I/O - 大约 4 个 I/O。然而,当寻找一个不存在的值时,事情会发生惊人的变化:
SELECT 1
FROM q8806566
WHERE Column_A = 20
AND ROWNUM = 1;
20-40 秒的执行时间,超过 100,000 个 I/O。
但是,如果我们添加索引:
create index q8806566_idx01 on q8806566 (column_a) tablespace users;
exec dbms_stats.gather_index_stats (ownname => user, indname => 'q8806566_idx01');
我们从两个查询中获得低于 0.1 秒的响应时间和个位数的 I/O。