number/date/varchar2类型字段做range scan 的selectivity计算

本文介绍Oracle数据库如何使用Standard Formula计算范围扫描的成本,特别是针对number和date类型的字段,通过具体实例展示了不同存储方式下选择性的计算方法。

oracle按照standard formula计算cost,当对于number/date类型字段做range scan, oracle都可以得到比较准确的selectivity. (之所以说是比较准确而非正确,因为虽然我们的数字、日期实际是离散的,但oracle optimizer认为是连续的,所以我们想查询2002-12-30-2003-01-05在2000-2004年(共1827天)中的selectivity,期望是7/1827,但oracle并不会这样计算)。

[@more@]

若以number类型存储年月日yyyymmdd 计算结果为:standard fomula:

selectivity=(required range) / (high value - low value) + 2/num_distinct

=(20030105-20021230)/(20041231-20000101) + 2/1827

= 8875 / 41130 +2/1827

=0.215779 + 0.001095

=0.216874

若以 char/varchar2类型存储年月日yyyymmdd ,并以此字段做range scan. oracle 也需要把字符串转为numeric数字. 再按照fomula计算selectivity.

字符串转成数字的方法以function实现。

rem
rem Script: template.sql
rem Author: Jonathan Lewis
rem Dated: Sep 2004
rem Purpose: Example for "Cost Based Oracle"
rem
rem Last tested:
rem 10.1.0.4
rem 9.2.0.6
rem 8.1.7.4
rem
rem Create a function that takes an input string
rem and returns the numeric value that the optimizer
rem would use to represent it.
rem
rem Inputs:
rem The string
rem The size limit if the string is to be
rem treated as a char() rather than varchar2()
rem
rem Special note:
rem This function will not work for multi-byte character sets.
rem

create or replace function cbo_char_value (
i_instring in varchar2,
i_charsize in number default 0
) return number
as
m_size number;
m_vc varchar2(15);
m_n number := 0;
begin
if i_charsize = 0 then
m_size := length(i_instring) ;
else
m_size := i_charsize ;
end if;

m_vc := rpad(rpad(i_instring,m_size,' '),15,chr(0));

for i in 1..15 loop

dbms_output.put(ascii(substr(m_vc,i,1)));
dbms_output.put(chr(9));
dbms_output.put_Line(
to_char(
power(256,15-i) * ascii(substr(m_vc,i,1)),
'999,999,999,999,999,999,999,999,999,999,999,999'
)
);
m_n := m_n + power(256,15-i) * ascii(substr(m_vc,i,1));
end loop;
return m_n;
end;
/


rem
rem Example of use:
rem

select
round(
1827 * (
2/1827 +
(cbo_char_value('20030105') - cbo_char_value('20021230')) /
(cbo_char_value('20041231') - cbo_char_value('20000101'))
),2
) cardinality
from
dual
;

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

转载于:http://blog.itpub.net/87149/viewspace-907288/

在QueryWrapper中对varchar2类型字段排序可以利用MyBatis-Plus提供的排序方法。MyBatis-Plus的`orderBy`里的参数最终是拼接在SQL语句的`order by`后面的,并非只能设置为数据库的列名称,只需使`orderBy`方法里的参数符合SQL中的排序规则,就能实现想要的排序结果[^3]。 以下是一些常见的排序方法示例: 1. **简单降序排序**: ```java import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import java.util.List; // 假设这是你的实体类 class YourEntity { // 实体类属性 } // 假设这是你的Mapper接口 interface YourMapper { List<YourEntity> selectList(QueryWrapper<YourEntity> wrapper); } public class Main { public static void main(String[] args) { QueryWrapper<YourEntity> wrapper = new QueryWrapper<>(); // 对varchar2类型字段hd_value进行降序排序 wrapper.orderByDesc("hd_value"); // 调用Mapper方法执行查询 YourMapper yourMapper = null; // 这里需要实际初始化Mapper List<YourEntity> list = yourMapper.selectList(wrapper); } } ``` 上述代码使用`orderByDesc`方法对`hd_value`字段进行降序排序,就像在引用[1]中展示的`fRiskListQueryWrapper.orderByDesc("hd_value")`一样。 2. **自定义多字段排序**: MyBatis-Plus还提供了其他排序方法,如`orderBy(boolean, boolean, String... columns)`、`orderByAsc(boolean, String... columns)`、`orderByAsc(String)`、`orderByAsc(String... columns)`、`orderByDesc(boolean, String... columns)`、`orderByDesc(String)`、`orderByDesc(String... columns)`等,可以根据需求进行多字段的自定义排序[^4]。 ```java QueryWrapper<YourEntity> wrapper = new QueryWrapper<>(); // 对varchar2类型字段hd_value进行降序排序,对另一个字段another_field进行升序排序 wrapper.orderByDesc("hd_value").orderByAsc("another_field"); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值