检查列上的索引
Check for index on a column
我们是否可以检查 table 中的特定列是否有索引?我正在使用 SQL Server Management Studio 2016。
我确实在网上搜索过,但所有的解决方案都在谈论在整个 table 而不是一列上寻找索引。
是的,您可以通过探索系统视图来做到这一点 sys.indexes and sys.index_columns。
例如,如果要查找 AdventureWorks 数据库中 table 'Production.BillOfMaterials' 中的 'StartDate' 列是否有索引,
您可以执行以下查询。
DECLARE @colName AS SYSNAME = 'StartDate'
DECLARE @tableName AS NVARCHAR(256) = 'Production.BillOfMaterials'
SELECT i.name AS index_name,
COL_NAME(ic.object_id, ic.column_id) AS column_name,
ic.index_column_id,
ic.key_ordinal,
ic.is_included_column
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
WHERE i.object_id = OBJECT_ID(@tableName)
AND COL_NAME(ic.object_id, ic.column_id) = @colName;
…结果如下
根据您的评论,我又创建了两个示例
首先 - 根据列名过滤
在下面的代码片段中有一个答案,为什么你不能得到想要的结果。 Object_Id 是基于模式的,因此只传递 table 没有模式的名称会产生 NULL 值。
在示例中,我根据 'StartDate' 列过滤 AdvantureWorks2016 数据库的系统视图
'
DECLARE @colName AS SYSNAME = 'StartDate'
--DECLARE @tableName AS NVARCHAR(256) = 'Production.BillOfMaterials'
SELECT i.name [Index Name],
OBJECT_SCHEMA_NAME(ic.object_id) + '.' + OBJECT_NAME(ic.object_id) [Table Name],
COL_NAME(ic.object_id, ic.column_id) [Column Name],
ic.index_column_id,
ic.key_ordinal,
ic.is_included_column
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
WHERE COL_NAME(ic.object_id, ic.column_id) = @colName
ORDER BY [Table Name]
结果如下图所示
根据tables
的列表进行二次过滤
如果您想缩小 table 的范围。假设您知道要检查的 table 的列表,您可以使用以下代码段。
DECLARE @tables AS TABLE
(
TableName NVARCHAR(256)
)
INSERT INTO @tables
VALUES
('HumanResources.EmployeeDepartmentHistory'),
('Production.BillOfMaterials'),
('Production.ProductCostHistory'),
('Production.ProductListPriceHistory')
SELECT i.name [Index Name],
OBJECT_SCHEMA_NAME(ic.object_id) + '.' + OBJECT_NAME(ic.object_id) [Table Name],
COL_NAME(ic.object_id, ic.column_id) [Column Name],
ic.index_column_id,
ic.key_ordinal,
ic.is_included_column
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
WHERE EXISTS
(
SELECT * FROM @tables t WHERE t.TableName = OBJECT_SCHEMA_NAME(ic.object_id) + '.' + OBJECT_NAME(ic.object_id)
)
ORDER BY [Table Name]
结果如下图所示。
我们是否可以检查 table 中的特定列是否有索引?我正在使用 SQL Server Management Studio 2016。 我确实在网上搜索过,但所有的解决方案都在谈论在整个 table 而不是一列上寻找索引。
是的,您可以通过探索系统视图来做到这一点 sys.indexes and sys.index_columns。
例如,如果要查找 AdventureWorks 数据库中 table 'Production.BillOfMaterials' 中的 'StartDate' 列是否有索引,
您可以执行以下查询。
DECLARE @colName AS SYSNAME = 'StartDate'
DECLARE @tableName AS NVARCHAR(256) = 'Production.BillOfMaterials'
SELECT i.name AS index_name,
COL_NAME(ic.object_id, ic.column_id) AS column_name,
ic.index_column_id,
ic.key_ordinal,
ic.is_included_column
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
WHERE i.object_id = OBJECT_ID(@tableName)
AND COL_NAME(ic.object_id, ic.column_id) = @colName;
…结果如下
根据您的评论,我又创建了两个示例
首先 - 根据列名过滤
在下面的代码片段中有一个答案,为什么你不能得到想要的结果。 Object_Id 是基于模式的,因此只传递 table 没有模式的名称会产生 NULL 值。
在示例中,我根据 'StartDate' 列过滤 AdvantureWorks2016 数据库的系统视图 '
DECLARE @colName AS SYSNAME = 'StartDate'
--DECLARE @tableName AS NVARCHAR(256) = 'Production.BillOfMaterials'
SELECT i.name [Index Name],
OBJECT_SCHEMA_NAME(ic.object_id) + '.' + OBJECT_NAME(ic.object_id) [Table Name],
COL_NAME(ic.object_id, ic.column_id) [Column Name],
ic.index_column_id,
ic.key_ordinal,
ic.is_included_column
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
WHERE COL_NAME(ic.object_id, ic.column_id) = @colName
ORDER BY [Table Name]
结果如下图所示
根据tables
的列表进行二次过滤如果您想缩小 table 的范围。假设您知道要检查的 table 的列表,您可以使用以下代码段。
DECLARE @tables AS TABLE
(
TableName NVARCHAR(256)
)
INSERT INTO @tables
VALUES
('HumanResources.EmployeeDepartmentHistory'),
('Production.BillOfMaterials'),
('Production.ProductCostHistory'),
('Production.ProductListPriceHistory')
SELECT i.name [Index Name],
OBJECT_SCHEMA_NAME(ic.object_id) + '.' + OBJECT_NAME(ic.object_id) [Table Name],
COL_NAME(ic.object_id, ic.column_id) [Column Name],
ic.index_column_id,
ic.key_ordinal,
ic.is_included_column
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
WHERE EXISTS
(
SELECT * FROM @tables t WHERE t.TableName = OBJECT_SCHEMA_NAME(ic.object_id) + '.' + OBJECT_NAME(ic.object_id)
)
ORDER BY [Table Name]
结果如下图所示。