表字段的定义,null还是not null?
来源:互联网 发布:手机淘宝关注是收藏吗 编辑:程序博客网 时间:2024/05/02 01:39
一个分页查询SQL,T1表有3千多万条记录,SQL执行一次需要19秒:
SELECT B2.* FROM
( SELECT B1.*, ROWNUM rnum
FROM ( SELECT /*+ index_desc(t1 IDX_BAS_PAPPVACTINFO_0001) */
T1.PA_CLINAME AS T1__PA_CLINAME ,
......
T1.PA_OPTIME AS T1__PA_OPTIME
FROM CDMBAS.BAS_PAPPVACTINFO T1
WHERE 1=1
ORDER BY PA_REQUNO DESC ,
PA_ORDER DESC
) B1
WHERE ROWNUM <= 21
) B2
WHERE rnum > 0 ;
执行计划:
检查发现,在order by上使用的两个字段上存在联合索引,但是优化器没有使用。即使使用index的hint也没有使用索引。
再检查表结构,order by使用的两个字段都是可以为空(NULL)。Btree索引是不保存全为NULL的值,所以优化器为了保证查询结果的准确性,不可能使用索引(如果全为null的记录也是SQL的结果,那么只扫描索引就无法得出这些记录)。
跟业务人员沟通,这两个字段都不可能为空,因为,SQL可以改写为(其中红色部分也可以换成另外一个order by 的字段):
SELECT B2.*
FROM
(
SELECT B1.*,
ROWNUM rnum
FROM
(
SELECT
T1.PA_CLINAME AS T1__PA_CLINAME ,
T1.PA_REQUNO AS T1__PA_REQUNO ,
T1.PA_CLICODE AS T1__PA_CLICODE ,
T1.PA_STATUS AS T1__PA_STATUS ,
T1.PA_APPVITEM AS T1__PA_APPVITEM ,
'¨¢¡Â3¨¬?¡¤?¨²¨®?¨º¡À' AS EA_USTIME ,
T1.PA_OPTKIND AS T1__PA_OPTKIND ,
T1.PA_CURRKIND AS T1__PA_CURRKIND ,
T1.PA_SUM AS T1__PA_SUM ,
T1.PA_OPRID AS T1__PA_OPRID ,
T1.PA_OPRNAME AS T1__PA_OPRNAME ,
T1.PA_OPINSTCODE AS T1__PA_OPINSTCODE,
T1.PA_OPINSTNAME AS T1__PA_OPINSTNAME,
T1.PA_OPDATE AS T1__PA_OPDATE ,
T1.PA_OPTIME AS T1__PA_OPTIME
FROM CDMBAS.BAS_PAPPVACTINFO T1
WHERE 1=1 and PA_REQUNO is not null
ORDER BY PA_REQUNO DESC ,
PA_ORDER DESC
)
B1
WHERE ROWNUM <= 21
)
B2
WHERE rnum > 0
这时SQL执行时间只需要几毫秒(sql monitor下面显示为0):
如果不改写SQL,而是更改表结构的定义,将两个字段其中任意一个从NULL改成NOT NULL,也是一样的效果。
看了这个案例,你还会对你的表字段的NULL还是NOT NULL随便定义吗?
顺便说一句,在使用NOT IN(select xxx from table)的SQL时,如果xxx的定义为NULL,在数据量大的时候,这个SQL的执行效率也是非常差的。NOT EXISTS不会受影响,但是这两个SQL不是等价的,NOT IN后面的结果集如果有NULL,那么整个SQL的结果为空;而NOT EXISTS不受结果集里面NULL记录的影响。
- 表字段的定义,null还是not null?
- 为表字段增加 not null约束的风险
- SQL建表字段语法DEFAULT和字段 NULL的组合定义表现
- SQLServer 表字段为 NULL 而视图为NOT NULL 问题
- mysql 表字段避免null 会带来额外的开销
- MySQL中可为空的字段设置为NULL还是NOT NULL
- oracle 定义表字段域的数据类型
- Mybatis框架实体类字段与数据库表字段不一致导致查询该字段的值一直为null
- 改变null not null
- null 与 not null
- mysql 【null】【not null】 ""
- NULL¬ NULL
- not null
- mysql not null 的影响
- MySQL的not null default
- Db2数据库中错误提示:23502,不能把null 直插入到定义为not null 的列中
- mysql <> null != null is not null
- DACL, NULL or not NULL
- Mysql源码方式安装与完全卸载Mysql
- 机器学习方法(五):逻辑回归Logistic Regression,Softmax Regression
- python 使用 simplejson 将字符串转换成字典dict
- intellij idea忽略部分类编译错误 (Eclipse-like incremental compilation )
- java网络编程
- 表字段的定义,null还是not null?
- 计算机网络之数据包的传递过程解析
- C++ 的 const和const_cast
- 指针和引用有什么区别
- js文件的编码问题
- Android中的简单图像处理
- ZOJ 3879 — Capture the Flag
- git学习(分支管理)
- Subsets II -- leetcode