Oracle什么样的列必须创建索引

有人说基数高的列,有人说在where条件中的列。当一个列选择性大于20%,说明该列的数据分布就比较均衡了。因此,当一个列出现在where条件中,该列没有创建索引并且选择选择性大于20%,那么该列就必须创建索引,从而提升SQL查询性能。
具体步骤如下:
1、先执行下面的存储过程,刷新数据库监控信息

BEGIN
  DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;
END;

2、再运行查询语句就可以查询出哪个表的哪个列出现在WHERE条件中

SELECT R.NAME              AS OWNER, --用户
       O.NAME              AS TABLE_NAME, --表
       C.NAME              AS COLUMN_NAME, --列
       U.EQUALITY_PREDS, --等值过滤
       U.EQUIJOIN_PREDS, --等值JOIN
       U.NONEQUIJOIN_PREDS, --不等JOIN
       U.RANGE_PREDS, --范围过滤次数 > >= < <=  BETWEEN AND
       U.LIKE_PREDS, --LIKE过滤
       U.NULL_PREDS, --NULL过滤
       TIMESTAMP
  FROM SYS.USER$ R
 INNER JOIN SYS.OBJ$ O
    ON R.USER# = O.OWNER#
 INNER JOIN SYS.COL_USAGE$ U
    ON O.OBJ# = U.OBJ#
 INNER JOIN SYS.COL$ C
    ON U.OBJ# = C.OBJ#
   AND U.INTCOL# = C.COL#
 WHERE R.NAME = 'HLHT_ARCH' /*用户*/
   and o.name = 'BASEINFO' /*表*/;

3、查询出选择性大于等于20%的列

SELECT B.OWNER,
       B.TABLE_NAME,
       A.column_name,
       ROUND(A.NUM_DISTINCT / B.NUM_ROWS*100,2) AS SELECTIVITY
  FROM DBA_TABLES B
 INNER JOIN DBA_TAB_COL_STATISTICS A
    ON B.OWNER = A.OWNER
   AND B.TABLE_NAME = A.TABLE_NAME
 WHERE B.OWNER = 'HLHT_ARCH'
   AND B.TABLE_NAME = 'BASEINFO'
   AND A.NUM_DISTINCT / B.NUM_ROWS >= 0.2 /*选择性大于20%*/

4、确保这些列没有创建索引

SELECT S.TABLE_OWNER, S.TABLE_NAME, S.COLUMN_NAME, S.INDEX_NAME
  FROM DBA_IND_COLUMNS S
 WHERE S.TABLE_OWNER = 'HLHT_ARCH'
   AND S.TABLE_NAME = 'BASEINFO'

5、把全部脚本组合起来,就可以得到全自动优化脚本了

BEGIN
  DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;
END;
SELECT S.TABLE_OWNER,
       S.TABLE_NAME,
       S.COLUMN_NAME,
       S.NUM_DISTINCT,
       S.NUM_ROWS,
       S.SELECTIVITY,
       'Need Index' AS NOTICE
  FROM (SELECT B.OWNER AS TABLE_OWNER,
               B.TABLE_NAME,
               A.COLUMN_NAME,
               A.NUM_DISTINCT,
               B.NUM_ROWS,
               ROUND(A.NUM_DISTINCT / DECODE(B.NUM_ROWS, 0, 1, B.NUM_ROWS) * 100,
                     2) AS SELECTIVITY
          FROM DBA_TABLES B
         INNER JOIN DBA_TAB_COL_STATISTICS A
            ON B.OWNER = A.OWNER
           AND B.TABLE_NAME = A.TABLE_NAME) S
 WHERE 1 = 1
   AND EXISTS (SELECT 1
          FROM (SELECT R.NAME    AS TABLE_OWNER, --用户
                       O.NAME    AS TABLE_NAME, --表
                       C.NAME    AS COLUMN_NAME, --列
                       TIMESTAMP
                  FROM SYS.USER$ R
                 INNER JOIN SYS.OBJ$ O
                    ON R.USER# = O.OWNER#
                 INNER JOIN SYS.COL_USAGE$ U
                    ON O.OBJ# = U.OBJ#
                 INNER JOIN SYS.COL$ C
                    ON U.OBJ# = C.OBJ#
                   AND U.INTCOL# = C.COL#) W
         WHERE S.TABLE_OWNER = W.TABLE_OWNER
           AND S.TABLE_NAME = W.TABLE_NAME
           AND S.COLUMN_NAME = W.COLUMN_NAME) /*列在WHERE条件中*/
   AND NOT EXISTS (SELECT 1
          FROM (SELECT S.TABLE_OWNER,
                       S.TABLE_NAME,
                       S.COLUMN_NAME,
                       S.INDEX_NAME
                  FROM DBA_IND_COLUMNS S) D
         WHERE S.TABLE_OWNER = D.TABLE_OWNER
           AND S.TABLE_NAME = D.TABLE_NAME
           AND S.COLUMN_NAME = D.COLUMN_NAME) /*列没有创建索引*/
   AND S.SELECTIVITY >= 20 /*列选择性大于20*/
   AND S.TABLE_OWNER IN( USER)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ben@dw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值