表和视图索引比较和CTE迭代

如何解决表和视图索引比较和CTE迭代

作为练习,我写了一个小脚本

  1. 查找给定表上的索引和列
  2. 查找依赖于该表的索引视图(及其列)
  3. 将视图上的索引与表上的索引进行比较,以查看是否有任何索引视图相同。

这第三步给我带来了问题。我似乎无法理解进行迭代和比较。正在考虑使用 CTE 来比较每个索引列,但结果不正确。任何帮助都是最有帮助的。

DECLARE @table_name VARCHAR(1000)
SET @table_name = 'dbo.tableName'

DROP TABLE IF EXISTS tempdb.dbo.#tmp_TableIndexesAndColumns; --
DROP TABLE IF EXISTS tempdb.dbo.#tmp_ViewsIndexesAndColumns;
--------------------------------------------------------
-- qTable - Get Table Indexes and their Columns
--------------------------------------------------------
CREATE TABLE #tmp_TableIndexesAndColumns
(
    tmpID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,table_schema_id INT NOT NULL,table_schema VARCHAR (5) NOT NULL,table_id INT NOT NULL,table_name VARCHAR(1000) NOT NULL,table_index_id INT NOT NULL,table_index_name VARCHAR(1000) NOT NULL,table_index_type_id INT NOT NULL,table_index_type VARCHAR(50) NOT NULL,table_is_unique BIT NOT NULL,table_column_id INT NOT NULL,table_column_name VARCHAR(1000) NOT NULL,table_is_included BIT NOT NULL
);

INSERT INTO #tmp_TableIndexesAndColumns
SELECT 
    obj_table.schema_id,SCHEMA_NAME(obj_table.schema_id),obj_table.object_id,obj_table.[name] AS table_name,i.index_id index_id,i.[name] AS index_name,i.[type] AS index_type_id,CASE
           WHEN i.[type] = 1 THEN
               'Clustered index'
           WHEN i.[type] = 2 THEN
               'Nonclustered unique index'
           WHEN i.[type] = 3 THEN
               'XML index'
           WHEN i.[type] = 4 THEN
               'Spatial index'
           WHEN i.[type] = 5 THEN
               'Clustered columnstore index'
           WHEN i.[type] = 6 THEN
               'Nonclustered columnstore index'
           WHEN i.[type] = 7 THEN
               'Nonclustered hash index'
           ELSE
               ''
       END AS index_type,i.is_unique,col_idx.column_id,col_idx.[name] AS [column_name],col_idx.is_included_column
FROM sys.objects obj_table
    INNER JOIN sys.indexes i
        ON obj_table.object_id = i.object_id
    CROSS APPLY
(
    SELECT col.column_id,col.[name],ic.is_included_column
    FROM sys.index_columns ic
        INNER JOIN sys.columns col
            ON ic.object_id = col.object_id
               AND ic.column_id = col.column_id
    WHERE ic.object_id = obj_table.object_id
          AND ic.index_id = i.index_id
) col_idx
WHERE obj_table.object_id = OBJECT_ID(@table_name)
      AND obj_table.is_ms_shipped <> 1
      AND i.index_id > 0
ORDER BY i.index_id,col_idx.column_id ;

--------------------------------------------------------
--  qTable - Get View Indexes and their Columns
--  (Views that Referencing Our Table)
--------------------------------------------------------
CREATE TABLE #tmp_ViewsIndexesAndColumns
(
    tmpID INT IDENTITY(1,view_schema_id INT NOT NULL,view_schema VARCHAR (5) NOT NULL,view_id INT NOT NULL,view_name VARCHAR(1000) NOT NULL,view_index_id INT NOT NULL,view_index_name VARCHAR(1000) NOT NULL,view_index_type_id INT NOT NULL,view_index_type VARCHAR(50) NOT NULL,view_is_unique BIT NOT NULL,referenced_column_id INT NOT NULL,referenced_column_name VARCHAR(1000) NOT NULL,referenced_is_included BIT NOT NULL
);

INSERT INTO #tmp_ViewsIndexesAndColumns
SELECT disTINCT 
    obj_view.schema_id,SCHEMA_NAME(obj_view.schema_id) AS view_schema,obj_view.object_id,obj_view.[name] AS view_name,i.index_id,col_idx.is_included_column
FROM sys.objects obj_table
JOIN sys.sql_expression_dependencies sed
     on sed.referenced_id = obj_table.object_id
join sys.objects obj_view
     on sed.referencing_id = obj_view.object_id
    JOIN sys.indexes i
        ON obj_view.object_id = i.object_id
    CROSS APPLY
(
    SELECT col.column_id,ic.is_included_column
    FROM sys.index_columns ic
        INNER JOIN sys.columns col
            ON ic.object_id = col.object_id
               AND ic.column_id = col.column_id
    WHERE ic.object_id = obj_view.object_id
          AND ic.index_id = i.index_id
) col_idx
WHERE obj_table.object_id = OBJECT_ID(@table_name)
      AND obj_view.is_ms_shipped <> 1
      AND i.index_id > 0
 ORDER BY obj_view.object_id,i.[name];

--------------------------------------------------------
--  qCompare - Find Identical View and Table Indexes
--------------------------------------------------------
WITH cte_table_index AS
(SELECT 
     ROW_NUMBER()  OVER (PARTITION BY tbl.table_index_id ORDER BY tbl.table_column_id) group_id,tbl.table_index_id,tbl.table_column_id
      FROM #tmp_TableIndexesAndColumns tbl
      UNION ALL       
      SELECT
     ROW_NUMBER()  OVER (PARTITION BY tbl.table_index_id ORDER BY tbl.table_column_id) group_id,vw.view_index_id,vw.referenced_column_id
FROM #tmp_TableIndexesAndColumns tbl
INNER JOIN #tmp_ViewsIndexesAndColumns vw
ON tbl.table_column_id = vw.referenced_column_id)
SELECT * FROM cte_table_index


DROP TABLE IF EXISTS tempdb.dbo.#tmp_TableIndexesAndColumns; 
DROP TABLE IF EXISTS tempdb.dbo.#tmp_ViewsIndexesAndColumns;

先谢谢你!

解决方法

这是我的尝试。

我们获取表的所有索引,匹配视图中的引用,连接表和视图的索引。

然后我们过滤如下:

两组索引列的全连接中不得存在任何内容。这个完全连接被过滤为只包含不匹配的索引列(内部 NOT EXISTS 只是对所有这些不同的东西进行可空比较的简写,这里没有 FROM):

SELECT 
    obj_table.schema_id,SCHEMA_NAME(obj_table.schema_id),obj_table.object_id,obj_table.[name] AS table_name,iT.index_id index_id,iT.[name] AS index_name,iT.[type] AS index_type_id,iT.type_desc AS index_type,iT.is_unique,obj_view.schema_id,SCHEMA_NAME(obj_view.schema_id) AS view_schema,obj_view.object_id,obj_view.[name] AS view_name,iV.index_id index_id,iV.[name] AS index_name,iV.[type] AS index_type_id,iV.type_desc AS index_type,iV.is_unique
FROM sys.objects obj_table
JOIN sys.indexes iT
    ON obj_table.object_id = iT.object_id
JOIN sys.sql_expression_dependencies sed
    on sed.referenced_id = obj_table.object_id
JOIN sys.objects obj_view
    on sed.referencing_id = obj_view.object_id
JOIN sys.indexes iV
    ON obj_view.object_id = iV.object_id

WHERE NOT EXISTS (SELECT 1
    FROM sys.index_columns icT
    INNER JOIN sys.columns colT
        ON icT.object_id = colT.object_id AND icT.column_id = colT.column_id
    -- outer ref
        AND icT.object_id = obj_table.object_id
        AND icT.index_id = iT.index_id

    FULL JOIN (sys.index_columns icV
        INNER JOIN sys.columns colV
            ON icV.object_id = colV.object_id AND icV.column_id = colV.column_id
        -- outer ref
        AND icV.object_id = obj_view.object_id
        AND icV.index_id = iV.index_id
    
    ) ON icV.index_column_id = icT.index_column_id

    WHERE NOT EXISTS (
      SELECT
        icT.index_column_id,icT.is_descending_key,icT.key_ordinal,colT.user_type_id,colT.max_length,colT.precision,colT.scale,colT.collation_name,colT.is_nullable
      INTERSECT
      SELECT
        icV.index_column_id,icV.is_descending_key,icV.key_ordinal,colV.user_type_id,colV.max_length,colV.precision,colV.scale,colV.collation_name,colV.is_nullable
    )
)

WHERE obj_table.object_id = OBJECT_ID(@table_name)
      AND obj_table.is_ms_shipped <> 1
      AND i.index_id > 0;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?