oracle查所有表的索引个数的示例代码实用指南

作者:袖梨 2026-09-01

平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“oracle查所有表的索引个数的示例代码”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。

1. 查看当前用户所有表的索引数量

SELECT 
    t.table_name,
    COUNT(i.index_name) as index_count,
    LISTAGG(i.index_name, ', ') WITHIN GROUP (ORDER BY i.index_name) as index_names
FROM user_tables t
LEFT JOIN user_indexes i ON t.table_name = i.table_name
GROUP BY t.table_name
ORDER BY COUNT(i.index_name) DESC, t.table_name;

2. 查看所有用户所有表的索引数量(需DBA权限)

SELECT 
    i.table_owner,
    i.table_name,
    COUNT(i.index_name) as index_count,
    LISTAGG(i.index_name, ', ') WITHIN GROUP (ORDER BY i.index_name) as index_names
FROM dba_indexes i
WHERE i.table_owner NOT IN ('SYS', 'SYSTEM', 'XDB', 'CTXSYS', 'MDSYS', 'ORDSYS') -- 排除系统用户
GROUP BY i.table_owner, i.table_name
ORDER BY i.table_owner, COUNT(i.index_name) DESC, i.table_name;

3.查询表及其索引的详细信息落到代码里,—建议采用,oracle国产化转换到tidb,最好明确知道所有需迁移的生产表的条数等令牌

SELECT 
    t.owner,
    t.table_name,
    t.num_rows as table_rows,
    COUNT(i.index_name) as total_indexes,
    SUM(CASE WHEN i.uniqueness = 'UNIQUE' THEN 1 ELSE 0 END) as unique_indexes,
    SUM(CASE WHEN i.uniqueness = 'NONUNIQUE' THEN 1 ELSE 0 END) as nonunique_indexes,
    SUM(CASE WHEN i.index_type = 'FUNCTION-BASED NORMAL' THEN 1 ELSE 0 END) as function_based_indexes
FROM dba_tables t
LEFT JOIN dba_indexes i ON t.owner = i.table_owner AND t.table_name = i.table_name
WHERE t.owner = 'YOUR_SCHEMA_NAME' -- 替换为你的模式名
GROUP BY t.owner, t.table_name, t.num_rows
ORDER BY COUNT(i.index_name) DESC, t.table_name;

4.按索引类型统计

SELECT 
    i.table_owner,
    i.table_name,
    i.index_type,
    COUNT(*) as count_per_type,
    LISTAGG(i.index_name, ', ') WITHIN GROUP (ORDER BY i.index_name) as index_list
FROM dba_indexes i
WHERE i.table_owner = 'YOUR_SCHEMA_NAME' -- 替换为你的模式名
GROUP BY i.table_owner, i.table_name, i.index_type
ORDER BY i.table_name, i.index_type;

5.查询没有索引的表

-- 查找当前用户下没有索引的表
SELECT
    t.table_name,
    t.num_rows,
    t.blocks
FROM user_tables t
WHERE NOT EXISTS (
    SELECT 1
    FROM user_indexes i
    WHERE i.table_name = t.table_name
)
AND t.table_name NOT LIKE 'BIN$%' -- 排除回收站中的表
ORDER BY t.num_rows DESC NULLS LAST;

-- 查找所有用户下没有索引的表(需要DBA权限)
SELECT
    t.owner,
    t.table_name,
    t.num_rows
FROM dba_tables t
WHERE NOT EXISTS (
    SELECT 1
    FROM dba_indexes i
    WHERE i.table_owner = t.owner
    AND i.table_name = t.table_name
)
AND t.owner NOT IN ('SYS', 'SYSTEM', 'XDB')
AND t.table_name NOT LIKE 'BIN$%'
ORDER BY t.owner, t.num_rows DESC NULLS LAST;

6.索引列数统计

-- 统计每个索引的列数
SELECT
    i.table_name,
    i.index_name,
    i.uniqueness,
    i.status,
    COUNT(ic.column_position) as column_count,
    LISTAGG(ic.column_name, ', ') WITHIN GROUP (ORDER BY ic.column_position) as columns
FROM user_indexes i
JOIN user_ind_columns ic ON i.index_name = ic.index_name
GROUP BY i.table_name, i.index_name, i.uniqueness, i.status
ORDER BY i.table_name, i.index_name;

7.实用的汇总查询

-- 索引统计汇总
WITH index_stats AS (
    SELECT
        owner,
        table_name,
        COUNT(*) as total_indexes,
        ROUND(AVG(blevel), 2) as avg_blevel,
        ROUND(AVG(leaf_blocks), 2) as avg_leaf_blocks,
        SUM(CASE WHEN status != 'VALID' THEN 1 ELSE 0 END) as invalid_indexes
    FROM dba_indexes
    WHERE owner = 'YOUR_SCHEMA_NAME'
    GROUP BY owner, table_name
)
SELECT
    owner,
    COUNT(DISTINCT table_name) as tables_with_indexes,
    SUM(total_indexes) as total_index_count,
    ROUND(AVG(total_indexes), 2) as avg_indexes_per_table,
    ROUND(MEDIAN(total_indexes), 2) as median_indexes_per_table,
    MAX(total_indexes) as max_indexes_in_table,
    SUM(invalid_indexes) as total_invalid_indexes
FROM index_stats
GROUP BY owner;

8.生产监控大表无索引情况

-- 查找行数超过10000但索引数少于2个的表
SELECT
    t.owner,
    t.table_name,
    t.num_rows,
    COUNT(i.index_name) as index_count
FROM dba_tables t
LEFT JOIN dba_indexes i ON t.owner = i.table_owner AND t.table_name = i.table_name
WHERE t.num_rows > 10000
AND t.owner = 'YOUR_SCHEMA_NAME'
GROUP BY t.owner, t.table_name, t.num_rows
HAVING COUNT(i.index_name) < 2
ORDER BY t.num_rows DESC;

9.查看索引采用情况(需Oracle 11g及以上)

SELECT 
    table_name,
    index_name,
    used
FROM v$object_usage
WHERE used = 'NO' -- 查看未使用的索引
ORDER BY table_name;

10.生成新建索引的脚本

SELECT 
    'CREATE INDEX idx_' || table_name || '_' || column_name ||
    ' ON ' || table_name || '(' || column_name || ');' as create_index_sql
FROM (
    SELECT DISTINCT
        t.table_name,
        tc.column_name
    FROM user_tables t
    JOIN user_tab_columns tc ON t.table_name = tc.table_name
    WHERE NOT EXISTS (
        SELECT 1
        FROM user_ind_columns ic
        WHERE ic.table_name = t.table_name
        AND ic.column_name = tc.column_name
    )
    AND t.table_name NOT LIKE 'BIN$%'
    AND tc.column_name NOT LIKE '%ID' -- 排除ID列
    AND tc.data_type IN ('VARCHAR2', 'CHAR', 'NUMBER', 'DATE') -- 只对某些数据类型创建索引
)
WHERE ROWNUM <= 10; -- 限制生成的数量

到此这篇关于oracle查所有表的索引个数的示例的文章就介绍到这了,更多相关oracle查所有表索引个数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多兼容脚本之家!

您可能感兴趣的文章:
  • Oracle数据库索引查询方式
  • Oracle查询表结构建表语句索引等方式
  • oracle中如何查询所有用户表的表名、主键名称、索引及外键等
  • Oracle表索引查看常用的方法总结
  • Oracle如何查询表索引和索引字段
  • Oracle如何借助执行计划查看查询语句是否采用索引
  • ORACLE检查找出损坏索引(Corrupt Indexes)的方法详解
  • Oracle中检查外键是否有索引的SQL脚本分享
  • oracle 索引的相关介绍(新建、简介、技巧、怎样查看) .
  • Oracle中检查是否需重构索引的sql

相关文章

精彩推荐