【发布时间】:2014-02-11 16:47:57
【问题描述】:
我正在尝试将有关索引使用情况的数据插入到各种控制数据库中。我正在使用的查询如下。我遇到的问题是,当我从控制数据库执行查询时(我们称之为 A)它返回 0 个结果,但如果我从源数据库执行它(让我们称之为 B)它运行得很好..
为什么?
在 SQL Server 2012 DEV 和 SQL Server 2008 EE 上都可以看到此行为。
示例 1 返回零结果:
USE A;
INSERT INTO A.dbo.UnusedIndexes
SELECT
DB_NAME() AS DatabaseName
, SCHEMA_NAME(o.Schema_ID) AS SchemaName
, OBJECT_NAME(o.object_id) AS TableName
, ix.name AS IndexName
,((SUM(ps.used_page_count)over(partition by ix.index_id))*8)/1024 AS [IndexSizeMB]
, ix_usage_stats.user_updates
, ix_usage_stats.user_seeks + ix_usage_stats.user_scans + ix_usage_stats.user_lookups
AS [User_SeeksScansLookups]
, ix_usage_stats.system_updates
, ix_usage_stats.system_seeks + ix_usage_stats.system_scans + ix_usage_stats.system_lookups
AS [System_SeeksScansLookups]
, NULL as [Drop_Statement]
, NULL as [Create_statement]
,getdate() as [date_added]
FROM B.sys.indexes ix
Left join B.sys.dm_db_index_usage_stats ix_usage_stats
ON ix_usage_stats.object_id = ix.object_id
AND ix_usage_stats.index_id = ix.index_id
INNER JOIN B.sys.objects o ON ix.object_id = o.object_id
JOIN B.sys.dm_db_partition_stats ps ON ps.object_id = ix.object_id AND ix.index_id = ps.index_id
WHERE
ix.name IS NOT NULL -- exclude heaps
AND ix.type <> 1 -- exclude the clustered indexes
AND o.is_ms_shipped = 0 -- exclude system objects
AND o.type NOT IN('F', 'UQ') -- exclude the foreign keys and unique contraints
AND SCHEMA_NAME(o.schema_id) not in ('dbo','stats', 'reporting')
AND (ix_usage_stats.user_seeks = 0 or ix_usage_stats.user_seeks is NULL)
AND (ix_usage_stats.user_scans = 0 or ix_usage_stats.user_scans is null)
AND (ix_usage_stats.user_lookups = 0 or ix_usage_stats.user_lookups is null)
示例 2 返回预期结果,填充 A.dbo.UnusedIndexes:
USE B;
INSERT INTO A.dbo.UnusedIndexes
SELECT
DB_NAME() AS DatabaseName
, SCHEMA_NAME(o.Schema_ID) AS SchemaName
, OBJECT_NAME(o.object_id) AS TableName
, ix.name AS IndexName
,((SUM(ps.used_page_count)over(partition by ix.index_id))*8)/1024 AS [IndexSizeMB]
, ix_usage_stats.user_updates
, ix_usage_stats.user_seeks + ix_usage_stats.user_scans + ix_usage_stats.user_lookups
AS [User_SeeksScansLookups]
, ix_usage_stats.system_updates
, ix_usage_stats.system_seeks + ix_usage_stats.system_scans + ix_usage_stats.system_lookups
AS [System_SeeksScansLookups]
, NULL as [Drop_Statement]
, NULL as [Create_statement]
,getdate() as [date_added]
FROM B.sys.indexes ix
Left join B.sys.dm_db_index_usage_stats ix_usage_stats
ON ix_usage_stats.object_id = ix.object_id
AND ix_usage_stats.index_id = ix.index_id
INNER JOIN B.sys.objects o ON ix.object_id = o.object_id
JOIN B.sys.dm_db_partition_stats ps ON ps.object_id = ix.object_id AND ix.index_id = ps.index_id
WHERE
ix.name IS NOT NULL -- exclude heaps
AND ix.type <> 1 -- exclude the clustered indexes
AND o.is_ms_shipped = 0 -- exclude system objects
AND o.type NOT IN('F', 'UQ') -- exclude the foreign keys and unique contraints
AND SCHEMA_NAME(o.schema_id) not in ('dbo','stats', 'reporting')
AND (ix_usage_stats.user_seeks = 0 or ix_usage_stats.user_seeks is NULL)
AND (ix_usage_stats.user_scans = 0 or ix_usage_stats.user_scans is null)
AND (ix_usage_stats.user_lookups = 0 or ix_usage_stats.user_lookups is null)
这整天都有效:
USE A;
Select * from B.sys.indexes
任何帮助都会很好 - 不幸的是我无法从数据库 B 执行此操作,因此简单的解决方案将不起作用。
已解决
想通了。 DB_NAME() 是问题所在。删除它并将其设置为“B”作为数据库名称解决了这个问题。
【问题讨论】:
-
您知道
DB_NAME()将返回您当前上下文数据库的名称,而不是您在FROM和JOIN子句中指定的数据库。在您的第一个示例中,即使您从B获取数据,您也会返回A -
您是否尝试过删除您的
INSERT INTO A.dbo.UnusedIndexes语句并验证两个查询是否返回相同的结果? -
我明白这一点 - 但即使在查询中使用 DB_NAME() 时,它也会在从 A 执行时返回 0 行
-
是的-我尝试过选择-但这也不起作用..但我刚刚想通了-感谢您对 DB_NAME() 的评论..将其设置为常数可以解决问题.
-
验证数据库的表是否有某种限制?
标签: sql sql-server database sql-server-2008 tsql