未加索引的外键

时间:2011-11-12 03:08:47

标签: sql oracle sqlplus

我正在寻找与gui

显示相同功能的命令行命令
Unindexed Foreign Keys 

2 个答案:

答案 0 :(得分:4)

没有命令行命令(我知道)。但你可以自己动手。基本上你需要一个查询数据库来检查这些,这实际上是你的GUI工具必须做的事情。查询将类似于:

SELECT  FK.table_name, FK.constraint_name
FROM    user_constraints FK
WHERE   FK.constraint_type = 'R'
AND     EXISTS
        (   SELECT  FC.position, FC.column_name
            FROM    user_cons_columns FC
            WHERE   FC.constraint_name = FK.constraint_name
            MINUS
            SELECT  IC.column_position AS position, IC.column_name
            FROM    user_ind_columns IC
            WHERE   IC.table_name = FK.table_name
        )

注意:此SQL并不完美。可能会出现这样的情况:愚蠢地认为有一个指数下注并不是真的。在正确的位置具有列的多个不同索引可能会欺骗它。要正确执行此操作,您需要开始在内联视图中进行分组或使用分析函数来确保所有索引列都来自同一索引。所以我把它放在这个简单的版本中,大部分时间都可以使用。

然后你可以在sqlplus中运行这个SQL,或者你可以将它嵌入一个可以从命令行轻松运行的shell脚本中。粗略的是:

#!/bin/bash -ue

LOGIN="$1"
sqlplus -s << END_SQL
    $LOGIN
    SET PAGESIZE 5000
    SELECT  FK.table_name, FK.constraint_name
    FROM    user_constraints FK
    WHERE   FK.constraint_type = 'R'
    AND     EXISTS
            (   SELECT  FC.position, FC.column_name
                FROM    user_cons_columns FC
                WHERE   FC.constraint_name = FK.constraint_name
                MINUS
                SELECT  IC.column_position AS position, IC.column_name
                FROM    user_ind_columns IC
                WHERE   IC.table_name = FK.table_name
            )
/
END_SQL

然后您可以像这样运行并获得基本结果:

[user@centos5 sql]$ ./fk.sh scott/tiger@orcl

TABLE_NAME                     CONSTRAINT_NAME
------------------------------ ------------------------------
EMP                            FK_DEPTNO

答案 1 :(得分:3)

以下是一个应该每次都能正常运行的脚本,由Steve Adams提供:

-------------------------------------------------------------------------------
--
-- Script:  missing_fk_indexes.sql
-- Purpose: to check for locking problems with missing foriegn key indexes
-- For:     8.1 and higher
--
-- Copyright:   (c) Ixora Pty Ltd
-- Author:  Steve Adams
--
-------------------------------------------------------------------------------
@save_sqlplus_settings

column constraint_name noprint
column table_name format a48
break on constraint_name skip 1 on table_name

select /*+ ordered */
  n.name  constraint_name,
  u.name ||'.'|| o.name  table_name,
  c.name  column_name
from
  (
    select /*+ ordered */ distinct
      cd.con#,
      cd.obj#
    from
      sys.cdef$  cd,
      sys.tab$  t
    where
      cd.type# = 4 and          -- foriegn key
      t.obj# = cd.robj# and
      bitand(t.flags, 6) = 0 and    -- table locks enabled
      not exists (          -- not indexed
    select
      null
    from
      sys.ccol$  cc,
          sys.ind$  i,
      sys.icol$  ic
    where
          cc.con# = cd.con# and
          i.bo# = cc.obj# and
          bitand(i.flags, 1049) = 0 and     -- index must be valid
          ic.obj# = i.obj# and
      ic.intcol# = cc.intcol#
        group by
          i.obj#
        having
          sum(ic.pos#) = (cd.cols * cd.cols + cd.cols)/2
      )
  )  fk,
  sys.obj$  o,
  sys.user$  u,
  sys.ccol$  cc,
  sys.col$  c,
  sys.con$  n
where
  o.obj# = fk.obj# and
  o.owner# != 0 and         -- ignore SYS
  u.user# = o.owner# and
  cc.con# = fk.con# and
  c.obj# = cc.obj# and
  c.intcol# = cc.intcol# and
  n.con# = fk.con#
order by
  2, 1, 3
/

@restore_sqlplus_settings

希望有所帮助。