Hint - FIRST_ROWS

本文通过一个具体案例探讨了SQL查询优化的方法。针对一个查询速度较慢的问题,通过调整SQL语句和使用hint,成功将查询时间从20秒降低到1秒以内。文中详细介绍了OPTIMIZER_MODE参数的作用及其对查询效率的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

公司系统中有个界面的查询显示比较慢,显示首页的速度需要20s以上

同事把查询发给我讨论下如何优化,查询大概是这样

select a,b,c,d,e,col1,col2,col3…..col50 from table_a where ….

关于这个sql,有以下几点:

1 a,b,c,d,e已经建立了索引

2 selectcol1col50都是属性列属性比较多数据量比较大

3 where后的条件比较多,不一一列出

4 table_a的数据量大概是170万,查询的结果的数据量是2

 

因为数据库是10g,首先我使用了SQL Tuning Advisor看看Oracle有什么建议结果SQL Tuning Advisor没有任何建议

 

然后看这个查询的执行计划,发现个问题:查询没有走索引

 

如果将查询修改为select a,b,c,d,e from table_a where …,将属性列删除,查询肯定是走索引的,索引应该没有什么问题

 

研究了半天,发现没有走索引的原因就在于数据库的OPTIMIZER_MODEALL_ROWS

Value

Description

ALL_ROWS

The optimizer uses a cost-based approach for all SQL statements in the session regardless of the presence of statistics and optimizes with a goal of best throughput (minimum resource use to complete the entire statement). This is the default value.

FIRST_ROWS_n

The optimizer uses a cost-based approach, regardless of the presence of statistics, and optimizes with a goal of best response time to return the first n number of rows; n can equal 1, 10, 100, or 1000.

FIRST_ROWS

The optimizer uses a mix of cost and heuristics to find a best plan for fast delivery of the first few rows.

Note: Using heuristics sometimes leads the query optimizer to generate a plan with a cost that is significantly larger than the cost of a plan without applying the heuristic. FIRST_ROWS is available for backward compatibility and plan stability; use FIRST_ROWS_n instead.

如果OPTIMIZER_MODEALL_ROWS,SQL语句执行是不管统计的,而是要以最好的吞吐量为目地,吞吐量:使用最小的资源。这是一个默认值

如果OPTIMIZER_MODEFIRST_ROWSSQL语句的执行是以获取开始的行的速度性为目地的。

这里有两个注意点:

1 FIRST_ROWS有时意味着更大的COST

2 FIRST_ROWS是为了向后兼容,可以使用FIRST_ROWS_n代替

 

从我们系统的需求来看,

首先,修改系统级的OPTIMIZER_MODE是不可能的,因为系统比较大,不知道会出现什么问题

其次,修改Session级的OPTIMIZER_MODE也是不太可能的,因为一个Session可能处理很多的数据,修改可能会导致不可预知的后果

第三,由于界面上已经分页,用户对查询速度的体验以及转化为对首页的查询速度,为了改进用户的体验(原20s),必须让查询速度更快

第四,我们系统存在使用9i10g,并没有使用到8i,所以可以使用FIRST_ROWS_n

 

考虑几点后,我加上了/*+ FIRST_ROWS */这个hint

select /*+ FIRST_ROWS */a,b,c,d,e,col1,col2,col3…..col50 from table_a where …
测试的结果如下:

1 执行计划上,加hint后走的是索引

2 执行速度上,加hint前平均20s,加hint后第一次4s,之后每次1秒内

3 执行成本上,加hint前是17000多,加hint后是14000多,相差并不是很大

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22111412/viewspace-618393/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/22111412/viewspace-618393/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值