共計 4489 個字符,預計需要花費 12 分鐘才能閱讀完成。
自動寫代碼機器人,免費開通
這篇文章主要講解了“SQL Server 怎么找出數據庫中沒有索引的表”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學習“SQL Server 怎么找出數據庫中沒有索引的表”吧!
在 SQL Server 數據庫的維護中,我們經常需要巡檢,找出一些沒有索引的表,然后根據實際情況判斷是否需要增加索引。下面分享一個腳本,如何找出當前數據庫中沒有索引的表信息。
SELECT DISTINCT @@SERVERNAME AS [SERVER_NAME] ,DB_NAME() AS [DB_NAME] ,so.object_id AS [OBJECT_ID] ,SCHEMA_NAME(so.schema_id) + . +OBJECT_NAME(so.object_id) AS [TABLE_NAME] ,MAX(dmv.rows) AS [APPROXIMATE_ROWS] ,MAX(d.ColumnCount) AS [COLUMN_COUNT] FROM sys.objects so ( NOLOCK ) JOIN sys.indexes si ( NOLOCK ) ON so.object_id = si.object_id AND so.type IN ( N U , N V ) JOIN sysindexes dmv ( NOLOCK ) ON so.object_id = dmv.id AND si.index_id = dmv.indid FULL OUTER JOIN ( SELECT object_id , COUNT(1) AS ColumnCount FROM sys.columns (NOLOCK) GROUP BY object_id ) d ON d.object_id = so.object_id WHERE so.is_ms_shipped = 0 AND so.object_id NOT IN ( SELECT major_id FROM sys.extended_properties (NOLOCK) WHERE name = N microsoft_database_tools_support ) AND INDEXPROPERTY(so.object_id, si.name, IsStatistics) = 0 GROUP BY so.schema_id , so.object_id HAVING ( CASE OBJECTPROPERTY(MAX(so.object_id), TableHasClustIndex ) WHEN 0 THEN COUNT(si.index_id) - 1 ELSE COUNT(si.index_id) END = 0 ) ORDER BY [APPROXIMATE_ROWS] DESC;
上面腳本只能查詢當前數據庫中沒有索引的表,我們知道,生產環境中,一個實例下面往往有多個用戶數據庫,我們需要采集每個數據庫中沒有索引的表信息,那么上面腳本明顯有點硬傷,所以,重寫了這個腳本。
IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE id = OBJECT_ID( tempdb.dbo.#Database)) BEGIN DROP TABLE #Database; END CREATE TABLE #Database (database_id INT ,database_name NVARCHAR(128) ); INSERT INTO #Database SELECT database_id, name FROM sys.databases WHERE state_desc= ONLINE AND name NOT IN (master , msdb , tempdb , model , distribution) DECLARE @database_name NVARCHAR(128); DECLARE @database_id INT; DECLARE @cmdText NVARCHAR(MAX); SET @database_name = SET @database_id =1; IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE id = OBJECT_ID( tempdb.dbo.#TAB_NO_INDEX_INFO)) BEGIN DROP TABLE #TAB_NO_INDEX_INFO; END CREATE TABLE #TAB_NO_INDEX_INFO( [SERVER_NAME] [NVARCHAR](32) NULL, [INSTANCE_NAME] [NVARCHAR](64) NULL, [DATABASE_NAME] [NVARCHAR](32) NULL, [TABLE_NAME] [NVARCHAR](128) NULL, [OBJECT_ID] [INT] NULL, [APPROXIMATE_ROWS] [INT] NULL, [COLUMN_COUNT] [INT] NULL ); WHILE(1=1) BEGIN SELECT TOP 1 @database_id = database_id , @database_name = database_name FROM #Database WHERE database_id @database_id -- next database_name greater than @database_id ORDER BY database_id -- database_id order -- exit loop if no more name greater than the last one used If @@rowcount = 0 Break SET @cmdText= USE + @database_name + --GO INSERT INTO #TAB_NO_INDEX_INFO ( SERVER_NAME , INSTANCE_NAME , DATABASE_NAME , TABLE_NAME , OBJECT_ID , APPROXIMATE_ROWS , COLUMN_COUNT ) SELECT DISTINCT CAST(SERVERPROPERTY( MachineName) AS NVARCHAR(32)) AS [SERVER_NAME] , @@SERVICENAME AS [INSTANCE_NAME] , DB_NAME() AS [DATABASE_NAME] , SCHEMA_NAME(so.schema_id)+ . + OBJECT_NAME(so.object_id) AS [TABLE_NAME] , so.object_id AS [OBJECT_ID] , MAX(dmv.rows) AS [APPROXIMATE_ROWS] , MAX(d.ColumnCount) AS [COLUMN_COUNT] FROM sys.objects so ( NOLOCK ) JOIN sys.indexes si ( NOLOCK ) ON so.object_id = si.object_id AND so.type IN ( N U , N V ) JOIN sysindexes dmv ( NOLOCK ) ON so.object_id = dmv.id AND si.index_id = dmv.indid FULL OUTER JOIN ( SELECT object_id , COUNT(1) AS ColumnCount FROM sys.columns (NOLOCK) GROUP BY object_id ) d ON d.object_id = so.object_id WHERE so.is_ms_shipped = 0 AND so.object_id NOT IN ( SELECT major_id FROM sys.extended_properties (NOLOCK) WHERE name = N microsoft_database_tools_support ) AND INDEXPROPERTY(so.object_id, si.name, IsStatistics) = 0 GROUP BY so.schema_id , so.object_id HAVING ( CASE OBJECTPROPERTY(MAX(so.object_id), TableHasClustIndex ) WHEN 0 THEN COUNT(si.index_id) - 1 ELSE COUNT(si.index_id) END = 0 ) ORDER BY [APPROXIMATE_ROWS] DESC; PRINT @cmdText; EXEC ( @cmdText); --EXEC SP_EXECUTESQL @cmdText, N @database_name NVARCHAR(32) ,@database_name Delete Db From #Database Db WHERE database_id=@database_id; END SELECT * FROM #TAB_NO_INDEX_INFO ORDER BY APPROXIMATE_ROWS DESC; -- 找出數據量超過 1000 行沒有索引信息的表 SELECT * FROM #TAB_NO_INDEX_INFO WHERE APPROXIMATE_ROWS 1000 ORDER BY APPROXIMATE_ROWS DESC
當你維護了很多 SQL Server 數據庫時,使用上面腳本到每臺 SQL Server 實例上跑一次,也是一件非常麻煩耗時的事情,所以還是需要自動化作業處理,定時使用 Python 腳本去每臺 SQL Server 實例上采集數據存儲下來,然后 DBA 只需做好兩件事情:監控采集數據和分析處理數據。這里就不貼 Python 腳本了,其實就是循環所有 SQL Server 實例,運行上面腳本,將采集到的相關數據存儲起來。
感謝各位的閱讀,以上就是“SQL Server 怎么找出數據庫中沒有索引的表”的內容了,經過本文的學習后,相信大家對 SQL Server 怎么找出數據庫中沒有索引的表這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關知識點的文章,歡迎關注!
向 AI 問一下細節