Yer*_*yan 2 oracle hibernate sql-order-by sql-optimization
我正在进行类似这样的查询,需要6秒才能完成:
select *
from ( select aaa."ID"
from "aaa"
where aaa."DELETED" is null
order by aaa."CREATED" desc )
where rownum <= 15;
Run Code Online (Sandbox Code Playgroud)
我的表中有大约160万条记录,我尝试在已删除的列和已创建的列中添加单独的索引,我尝试添加包含已创建和已删除的colunms的索引,并尝试创建相同的索引以不同的顺序.似乎没有任何帮助.我该怎么做才能加快速度呢?
我无法更改查询因为它是由hibernate生成的
编辑:即使没有aaa."DELETED" is null查询运行速度很慢.
编辑2:

编辑3:添加我的索引定义.老实说,我不知道大多数这些数字是什么意思,我使用sqldeveloper来创建索引.甚至不知道每个索引有如此多的配置选项,我现在将查看文档.
CREATE INDEX "aaa"."aaa_CREATED_ASC" ON "aaa"."aaa"
(
"CREATED"
)
PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE
(
INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT
)
TABLESPACE "SYSTEM" ;
CREATE INDEX "aaa"."aaa_CREATED_DESC" ON "aaa"."aaa"
(
"CREATED" DESC
)
PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE
(
INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT
)
TABLESPACE "SYSTEM" ;
Run Code Online (Sandbox Code Playgroud)
您需要了解Oracle如何访问数据库中的记录.索引读取是一个操作,表读取是另一个操作.因此,从表中检索一个索引记录至少需要两次读取.
您的查询使用三条信息:
Oracle不会为NULL值编制索引,因此单个列索引DELETED将无法帮助您.这是一个全表扫描,并没有比没有索引更好.
索引CREATED本身更好,因为访问路径将变为:
INDEX FULL SCAN DESCENDING
Run Code Online (Sandbox Code Playgroud)
也就是说,它开始是索引中的最新日期并向后工作.但是,查询仍然需要读取表以查找ID和DELETED值.这可能是很多表读取,具体取决于DELETED为空的频率.
现在,(CREATED, DELETED) 该顺序中的复合索引应该更有用,因为Oracle现在将索引DELETED列中的NULL .Oracle可以使用索引来确保它只查找表记录以获取ID值.那将是十五个表读.
最后,您可以在索引上构建复合索引(CREATED, DELETED, ID)并为整个查询提供服务.这是最快的选择.
然后,您只需确定性能优势是否证明维护索引的开销是合理的.对于它的价值而言,维护复合指数的成本只会增加一小部分列索引的成本.
顺便说一下,像这样的可怕查询是使用逻辑删除是个坏主意的一个原因.物理删除记录,并在需要时使用日记表来检索表的历史状态.
| 归档时间: |
|
| 查看次数: |
3957 次 |
| 最近记录: |