合 Oracle之COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主键)、COUNT(ROWID)、COUNT(非空列)、COUNT(允许为空列)、COUNT(DISTINCT 列名)等写法性能比较
Tags: Oraclecount(*)COUNT(1)COUNT(DISTINCT 列名)COUNT(ROWID)COUNT(主键)COUNT(允许为空列)COUNT(常量)COUNT(非空列)
前言部分
导读和注意事项
各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,\~O(∩_∩)O\~:
① COUNT(1)和COUNT(*)的区别(重点)
② 10046和10053的使用
③ “SELECT COUNT(列)”和“SELECT 列”在选择索引方面的区别
④ COUNT计数的优化
实验环境介绍
项目 | source db |
---|---|
db 类型 | RAC |
db version | 11.2.0.3.0 |
db 存储 | ASM |
OS版本及kernel版本 | RHEL 6.5 |
实验目标
弄清楚COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主键)、COUNT(ROWID)、COUNT(非空列)、COUNT(允许为空列)、COUNT(DISTINCT 列名)之间的区别,以及它们之间的效率问题。
实验过程
实验脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | --创建1W行的表 DROP TABLE T_COUNT_LHR; CREATE TABLE T_COUNT_LHR AS SELECT OBJECT_ID, OBJECT_NAME, OWNER, DATA_OBJECT_ID, OBJECT_TYPE, LAST_DDL_TIME FROM DBA_OBJECTS D WHERE D.OBJECT_ID IS NOT NULL AND D.OBJECT_NAME IS NOT NULL AND ROWNUM <= 10000; --更新空值, UPDATE T_COUNT_LHR t SET t.object_type='' WHERE Rownum<=5; UPDATE T_COUNT_LHR t SET t.LAST_DDL_TIME=T.LAST_DDL_TIME+ROWNUM; UPDATE T_COUNT_LHR t SET t.LAST_DDL_TIME='' WHERE Rownum<=1; COMMIT; --添加主键、非空约束、唯一索引、普通索引 ALTER TABLE T_COUNT_LHR ADD CONSTRAINT PK_OBJECT_ID PRIMARY KEY(OBJECT_ID); ALTER TABLE T_COUNT_LHR MODIFY OBJECT_NAME NOT NULL; CREATE UNIQUE INDEX IDX_LDT ON T_COUNT_LHR(LAST_DDL_TIME); CREATE INDEX IDX_DATA_OBJECT_ID ON T_COUNT_LHR(DATA_OBJECT_ID); CREATE INDEX IDX_DATA_OWNER ON T_COUNT_LHR(OWNER); ALTER TABLE T_COUNT_LHR MODIFY OWNER NOT NULL; --收集统计信息 EXEC dbms_stats.gather_table_stats(USER,'T_COUNT_LHR'); SELECT d.COLUMN_NAME,d.DATA_TYPE,d.NUM_NULLS,d.NUM_DISTINCT,d.LAST_ANALYZED FROM cols d WHERE d.TABLE_NAME='T_COUNT_LHR'; |
表的信息如下所示:
列名 | 是否主键 | 是否允许为空 | 是否有索引 | 数据类型 | 空值的行数 | 不同值的行数 | 总行数 |
---|---|---|---|---|---|---|---|
OBJECT_ID | Y | N | 唯一索引 | NUMBER | 0 | 10000 | 10000 |
OBJECT_NAME | N | 无 | VARCHAR2 | 0 | 8112 | 10000 | |
OWNER | N | 普通索引(IDX_OWNER) | VARCHAR2 | 0 | 5 | 10000 | |
DATA_OBJECT_ID | Y | 普通索引(IDX_DATA_OBJECT_ID) | NUMBER | 7645 | 2318 | 10000 | |
OBJECT_TYPE | Y | 无 | VARCHAR2 | 5 | 20 | 10000 | |
LAST_DDL_TIME | Y | 唯一索引(IDX_LDT) | DATE | 1 | 9999 | 10000 |
需要统计如下几种情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | SELECT COUNT(1) FROM T_COUNT_LHR;--走索引 SELECT COUNT(*) FROM T_COUNT_LHR;--走索引 SELECT COUNT(ROWID) FROM T_COUNT_LHR; --走索引 SELECT COUNT(OBJECT_ID) FROM T_COUNT_LHR; --走索引 SELECT COUNT(OBJECT_NAME) FROM T_COUNT_LHR;--走索引 SELECT COUNT(OWNER) FROM T_COUNT_LHR D;--走索引 SELECT COUNT(D.DATA_OBJECT_ID) FROM T_COUNT_LHR D; --走索引 SELECT COUNT(D.LAST_DDL_TIME) FROM T_COUNT_LHR D;--走索引 SELECT COUNT(D.LAST_DDL_TIME) FROM T_COUNT_LHR D WHERE D.LAST_DDL_TIME IS NOT NULL;--走索引 SELECT D.LAST_DDL_TIME FROM T_COUNT_LHR D; --不走索引 SELECT D.LAST_DDL_TIME FROM T_COUNT_LHR D WHERE D.LAST_DDL_TIME IS NOT NULL;--走索引 SELECT COUNT(DISTINCT DATA_OBJECT_ID) FROM T_COUNT_LHR D;--不走索引 SELECT COUNT(DISTINCT OWNER) FROM T_COUNT_LHR D;--走索引 SELECT COUNT(DISTINCT DATA_OBJECT_ID) FROM T_COUNT_LHR D WHERE DATA_OBJECT_ID IS NOT NULL ;--走索引 |