Oracle11g 如何在oracle中按行号查询
在Oracle中,有没有办法直接按表中的行号进行查询?换句话说,在一些基本语言(如C或Java)中实现与数组中普通查找相同的效果。我还没有尝试虚拟专栏 例如,下面是一个高效查询的示例,但它会浪费磁盘空间:Oracle11g 如何在oracle中按行号查询,oracle11g,query-optimization,Oracle11g,Query Optimization,在Oracle中,有没有办法直接按表中的行号进行查询?换句话说,在一些基本语言(如C或Java)中实现与数组中普通查找相同的效果。我还没有尝试虚拟专栏 例如,下面是一个高效查询的示例,但它会浪费磁盘空间: create table ary (row_position_id number(10) NOT NULL, datum binary_float NOT NULL); declare i pls_integer; begin for i in 0.
create table ary (row_position_id number(10) NOT NULL,
datum binary_float NOT NULL);
declare i pls_integer;
begin
for i in 0..10000000
loop
insert into ary values (i, dbms_random.normal());
end loop;
commit;
end;
create unique index ary_rp on ary(row_position_id);
现在,我将创建一组查询值以存储在另一个“参数”表中:
现在,有了这些查询值,我将查询原始表
select d.* from ary d where exists (select 0 from query_values v
where d.row_position_id = v.qval);
现在,这个查询就可以了——它将使用索引唯一扫描和ROWID对表的访问。我遇到的问题是,行位置id在表块中占用的空间与实际数据(基准列)一样多
我知道索引组织的表和虚拟列(不能与IOT一起使用)。当然,像ROWNUM和ROW_NUMBER这样的东西在这里是不相关的(除非我误解了什么)
同样值得指出的是,这个表是静态数据——一旦加载,它将永远不会更改。我可能会做一个只读的altertable
我真正想要的是:
create table ary (datum binary_float not null);
-- load rows in a specific order
-- efficiently query this table by implicit row position
非常感谢
亨利我想你会想保留额外的专栏。原因如下: 正如您所说,ROWNUM和ROW_NUMBER在这里不适用,因为它们是在查询中返回行时生成的;他们不会告诉您任何有关插入订单的信息 罗维德呢?ROWID是存储行的位置-同样,来自:
- 对象的数据对象编号
- 行所在的数据文件中的数据块
- 行在数据块中的位置(第一行为0)
- 行所在的数据文件(第一个文件是1)。文件号是相对于表空间的
DROP TABLE temp;
CREATE TABLE temp
( a number(10)
, b varchar2(10)
)
ROWDEPENDENCIES
;
-- one commit after all rows
INSERT INTO temp VALUES (1, 'A');
INSERT INTO temp VALUES (2, 'B');
INSERT INTO temp VALUES (3, 'C');
INSERT INTO temp VALUES (4, 'D');
INSERT INTO temp VALUES (5, 'E');
INSERT INTO temp VALUES (6, 'F');
COMMIT;
SELECT X.*, ROWNUM
FROM (SELECT T.*
, ORA_ROWSCN
FROM TEMP T
ORDER BY ORA_ROWSCN
) x
;
A B ORA_ROWSCN ROWNUM
1 A 2272340 1
2 B 2272340 2
6 F 2272340 3
4 D 2272340 4
5 E 2272340 5
3 C 2272340 6
哎呀,那些排绝对不是按顺序排的
现在每行使用一次提交:
TRUNCATE TABLE temp;
INSERT INTO temp VALUES (1, 'A');
COMMIT;
INSERT INTO TEMP VALUES (2, 'B');
COMMIT;
INSERT INTO temp VALUES (3, 'C');
COMMIT;
INSERT INTO temp VALUES (4, 'D');
COMMIT;
INSERT INTO temp VALUES (5, 'E');
COMMIT;
INSERT INTO temp VALUES (6, 'F');
COMMIT;
SELECT X.*, ROWNUM
FROM (SELECT T.*
, ORA_ROWSCN
FROM TEMP T
ORDER BY ORA_ROWSCN
) x
;
A B ORA_ROWSCN ROWNUM
1 A 2272697 1
2 B 2272699 2
3 C 2272701 3
4 D 2272703 4
5 E 2272705 5
6 F 2272707 6
更好。但是如果你有大量的行,它就不会很快进入。(我认为如果你有意放慢插入速度,你会这么做。)
我认为这与您尝试使用自己的列一样好,但仍然有希望节省存储:您可以取消表+索引,而只使用索引组织的表。它基本上是一个可以直接查询的索引
就这么简单:
CREATE TABLE TEMP2
( A NUMBER(10)
, B VARCHAR2(10)
, CONSTRAINT PK_CONSTRAINT PRIMARY KEY (A)
)
ORGANIZATION INDEX
;
还有其他参数,你也要考虑这个问题,但是更多信息检查…谢谢你,帕特里克。我恐怕这就是答案;)我已经对索引组织表进行了大量的实验,尽管它们在这种情况下表现得更好(而且我认为对于这个用例来说是合适的),但它们仍然与我认为最有效的解决方案相去甚远。我认为您没有尝试过巧妙地使用LOB和PL/SQL来表示相同的信息?除非您想引入上下文切换,否则我不会使用PL/SQL。(我刚刚读了一篇文章,其中12c允许在WITH子句中嵌入PL/SQL——显然绕过了上下文切换,但根据这里的标签,您使用的是11g,因此您将付出代价。)如果IOTs可以解决这种情况,那么您希望用lob之类的东西解决的一般情况是什么?我将尝试lob解决方案。我应该解释一下,我实际上想要的是二维数组,而不是一维数组。(1d将是设置2d数组的一般技术,但如果我不能直接使用它,那么可能需要一个LOB表,每个LOB代表数组中的一行。顺便说一句,我发现pl/sql非常有效。您只需要使用大容量sql和并行流水线表函数,并且有最小的上下文切换。
CREATE TABLE TEMP2
( A NUMBER(10)
, B VARCHAR2(10)
, CONSTRAINT PK_CONSTRAINT PRIMARY KEY (A)
)
ORGANIZATION INDEX
;