我正在编写一个存储过程,它将数据库名称作为参数并返回该数据库索引及其碎片级别的表。这个存储过程将存在于我们的 DBA 数据库(包含 DBA 用于监视和优化事物的表的数据库)中。如果有区别的话,所讨论的系统都是 SQL Server 2008 R2。
我已经完成了基本查询,但我一直在尝试提供索引的实际名称。据我所知,该信息包含在每个人的 sys.indexes 视图中。我的具体问题是尝试从另一个数据库的存储过程中以编程方式引用该视图。
为了说明,这是有问题的查询部分:
FROM sys.dm_db_index_physical_stats(@db_id,NULL,NULL,NULL,NULL) p
INNER JOIN sys.indexes b ON p.[object_id] = b.[object_id]
AND p.index_id = b.index_id
AND b.index_id != 0
Run Code Online (Sandbox Code Playgroud)
当从@db_id 标识的数据库执行时,查询工作正常,因为它使用了正确的 sys.indexes 视图。但是,如果我尝试从 DBA 数据库中调用它,则所有结果都为空,因为 sys.indexes 视图用于错误的数据库。
更笼统地说,我需要能够做这样的事情:
DECLARE @db_name NVARCHAR(255) = 'my_database';
SELECT * FROM @db_name + '.sys.indexes';
Run Code Online (Sandbox Code Playgroud)
或者
USE @db_name;
Run Code Online (Sandbox Code Playgroud)
我尝试使用字符串连接和 OBJECT_NAME/OBJECT_ID/DB_ID 函数的组合来切换数据库或引用其他数据库,但似乎没有任何效果。我很感激社区可能有的任何想法,但我怀疑我将不得不重新调整这个存储过程以驻留在每个单独的数据库中。
在此先感谢您的任何建议。
我们正在运行 SQL Server 2008。在查看我在 sys.dm_db_missing_index_* 视图上运行的查询结果时,我看到了一个关于包含列的奇怪建议。我有以下两个表:
create table foo (
id int not null identity(1,1) primary key
/* many more fields, not relevant to question */
)
create table bar (
id int not null identity(1,1) primary key
foo_id int not null,
param_name nvarchar(50),
param_value nvarchar(255)
)
Run Code Online (Sandbox Code Playgroud)
表 foo 与 bar 有 1:M 的关系;bar 用于存储与 foo 中的某些记录相关的杂项。
回到 sys.dm_db_missing_index_* 查询。一天中,优化器会在equality_columns 中查找foo_id 和included_columns 中的id 数次在bar 上查找索引。我的问题是,在非聚集索引中包含表的聚集索引键有什么意义?由于非聚簇索引的叶级无论如何都包含聚簇索引的键值,那么在非聚簇索引中包含聚簇索引键不是多余的吗?
编辑: bar 上唯一现有的索引是以 PK 作为键的聚集索引。
提前致谢。