/* Test index / fk retrieval query 02.11.2022, TSC */ USE [sandbox]; IF OBJECT_ID('dbo.parent') IS NULL BEGIN --DROP TABLE dbo.parent ALTER TABLE [dbo].[child] DROP CONSTRAINT IF EXISTS [fk_child__REF__parent]; CREATE TABLE [dbo].[parent] ([id] INT NOT NULL CONSTRAINT [pk_parent] PRIMARY KEY ([id])); PRINT 'parent table created'; END; IF OBJECT_ID('dbo.child') IS NULL BEGIN --DROP TABLE dbo.child; CREATE TABLE [dbo].[child] ([id] INT IDENTITY NOT NULL, [parent_id] INT NOT NULL, [ins_date] SMALLDATETIME NOT NULL CONSTRAINT [df_child_COL_insDate] DEFAULT CURRENT_TIMESTAMP CONSTRAINT [pk_child] PRIMARY KEY ([id])); PRINT 'child table created'; END; IF OBJECT_ID('fk_child__REF__parent') IS NULL BEGIN ALTER TABLE [dbo].[child] ADD CONSTRAINT [fk_child__REF__parent] FOREIGN KEY ([parent_id]) REFERENCES [dbo].[parent] ([id]); PRINT 'fk created'; END; IF INDEXPROPERTY(OBJECT_ID('child'), 'CIX_child_parent_id', 'IndexID') IS NULL BEGIN; CREATE NONCLUSTERED INDEX [CIX_child_parent_id] ON [dbo].[child] ([parent_id]); PRINT 'idx created'; END; TRUNCATE TABLE [dbo].[child]; DELETE FROM [dbo].[parent] WHERE 1 = 1; INSERT INTO [dbo].[parent] ([id]) VALUES (1); INSERT INTO [dbo].[child] ([parent_id]) VALUES (1); SELECT SCHEMA_NAME([tab].[schema_id]) + '.' + [tab].[name] AS [table], [col].[column_id], [col].[name] AS [column_name], CASE WHEN [fk].[object_id] IS NOT NULL THEN '>-' ELSE NULL END AS [rel], SCHEMA_NAME([pk_tab].[schema_id]) + '.' + [pk_tab].[name] AS [primary_table], [pk_col].[name] AS [pk_column_name], [fk_cols].[constraint_column_id] AS [NO], [fk].[name] AS [fk_constraint_name] FROM [sys].[tables] [tab] INNER JOIN [sys].[columns] [col] ON [col].[object_id] = [tab].[object_id] LEFT OUTER JOIN [sys].[foreign_key_columns] [fk_cols] ON [fk_cols].[parent_object_id] = [tab].[object_id] AND [fk_cols].[parent_column_id] = [col].[column_id] LEFT OUTER JOIN [sys].[foreign_keys] [fk] ON [fk].[object_id] = [fk_cols].[constraint_object_id] LEFT OUTER JOIN [sys].[tables] [pk_tab] ON [pk_tab].[object_id] = [fk_cols].[referenced_object_id] LEFT OUTER JOIN [sys].[columns] [pk_col] ON [pk_col].[column_id] = [fk_cols].[referenced_column_id] AND [pk_col].[object_id] = [fk_cols].[referenced_object_id] WHERE [fk].[object_id] IS NOT NULL --AND SCHEMA_NAME(tab.SCHEMA_ID) = 'dbo' --AND tab.name='customer' ORDER BY SCHEMA_NAME([tab].[schema_id]) + '.' + [tab].[name], [col].[column_id]; ;WITH [ColInfo] AS (SELECT [o].[name] AS [TblName], [s].[name] + '.' + [o].[name] AS [SchemaTbl], [i].[name] AS [IndexName], [i].[is_primary_key] AS [IsPrimaryKey], [i].[is_unique_constraint] AS [IsUniqueConstraint], [i].[is_unique] AS [IsUnique], [c].[name] AS [ColName], [c].[is_computed] AS [IsComputedCol], [ic].[is_included_column] AS [IsIncludedCol], [ic].[key_ordinal], [i].[filter_definition] AS [FilterDefinition] FROM [sys].[objects] [o] INNER JOIN [sys].[schemas] [s] ON [o].[schema_id] = [s].[schema_id] INNER JOIN [sys].[columns] [c] ON [o].[object_id] = [c].[object_id] INNER JOIN [sys].[indexes] [i] ON [c].[object_id] = [i].[object_id] INNER JOIN [sys].[index_columns] [ic] ON [i].[index_id] = [ic].[index_id] AND [o].[object_id] = [ic].[object_id] AND [c].[column_id] = [ic].[column_id]) --- Index Read/Write stats (all tables in current DB) ordered by Reads (Query 62) (Overall Index Usage - Reads) SELECT [o].[name] AS [tblName], [o].[type], [i].[name] AS [IndexName], [i].[index_id], [s].[user_seeks] + [s].[user_scans] + [s].[user_lookups] AS [Reads], [s].[user_updates] AS [Writes], CASE WHEN [s].[user_updates] > [s].[user_seeks] + [s].[user_scans] + [s].[user_lookups] THEN [s].[user_updates] - ([s].[user_seeks] + [s].[user_scans] + [s].[user_lookups]) ELSE ([s].[user_seeks] + [s].[user_scans] + [s].[user_lookups]) - [s].[user_updates] END AS [delta], [i].[type_desc] AS [IndexType], [i].[fill_factor] AS [FillFactor], [i].[has_filter], [i].[filter_definition], [s].[last_user_scan], [s].[last_user_lookup], [s].[last_user_seek], [idx_cols].[IndexColumns], [idx_cols].[IncludedColumns], [fk].[primary_table], [fk].[pk_column_name], [fk].[fk_constraint_name] FROM [sys].[dm_db_index_usage_stats] AS [s] WITH (NOLOCK) INNER JOIN [sys].[indexes] AS [i] WITH (NOLOCK) ON [s].[object_id] = [i].[object_id] INNER JOIN [sys].[objects] [o] WITH (NOLOCK) ON [s].[object_id] = [o].[object_id] OUTER APPLY ( SELECT DISTINCT [x].[TblName], [x].[IndexName], [x].[IsPrimaryKey], [x].[IsUniqueConstraint], [x].[IsUnique], --,size.IndexSizeKB [c].[IndexColumns], [ci].[IncludedColumns], [cc].[ComputedColumns], [x].[FilterDefinition] FROM [ColInfo] [x] CROSS APPLY ( SELECT STUFF([sq].[strXML], 1, 2, '') AS [IndexColumns] FROM ( SELECT ', ' + ISNULL([x2].[ColName], '') FROM [ColInfo] [x2] WHERE [x].[TblName] = [x2].[TblName] AND [x].[IndexName] = [x2].[IndexName] AND [x2].[IsIncludedCol] = 0 ORDER BY [x2].[key_ordinal] FOR XML PATH('')) [sq]([strXML]) ) [c] OUTER APPLY ( SELECT STUFF([sq].[strXML], 1, 2, '') AS [IncludedColumns] FROM ( SELECT ', ' + ISNULL([x2].[ColName], '') FROM [ColInfo] [x2] WHERE [x].[TblName] = [x2].[TblName] AND [x].[IndexName] = [x2].[IndexName] AND [x2].[IsIncludedCol] = 1 ORDER BY [x2].[key_ordinal] FOR XML PATH('')) [sq]([strXML]) ) [ci] OUTER APPLY ( SELECT STUFF([sq].[strXML], 1, 2, '') AS [ComputedColumns] FROM ( SELECT ', ' + ISNULL([x2].[ColName], '') FROM [ColInfo] [x2] WHERE [x].[TblName] = [x2].[TblName] AND [x].[IndexName] = [x2].[IndexName] AND [x2].[IsComputedCol] = 1 ORDER BY [x2].[key_ordinal] FOR XML PATH('')) [sq]([strXML]) ) [cc] WHERE [x].[TblName] = [o].[name] AND [x].[IndexName] = [i].[name]) [idx_cols] LEFT OUTER JOIN ( SELECT SCHEMA_NAME([tab].[schema_id]) + '.' + [tab].[name] AS [table], [col].[column_id], [col].[name] AS [column_name], CASE WHEN [fk].[object_id] IS NOT NULL THEN '>-' ELSE NULL END AS [rel], SCHEMA_NAME([pk_tab].[schema_id]) + '.' + [pk_tab].[name] AS [primary_table], [pk_col].[name] AS [pk_column_name], [fk_cols].[constraint_column_id] AS [NO], [fk].[name] AS [fk_constraint_name], [tab].[name] AS [tbl_name] FROM [sys].[tables] [tab] INNER JOIN [sys].[columns] [col] ON [col].[object_id] = [tab].[object_id] LEFT OUTER JOIN [sys].[foreign_key_columns] [fk_cols] ON [fk_cols].[parent_object_id] = [tab].[object_id] AND [fk_cols].[parent_column_id] = [col].[column_id] LEFT OUTER JOIN [sys].[foreign_keys] [fk] ON [fk].[object_id] = [fk_cols].[constraint_object_id] LEFT OUTER JOIN [sys].[tables] [pk_tab] ON [pk_tab].[object_id] = [fk_cols].[referenced_object_id] LEFT OUTER JOIN [sys].[columns] [pk_col] ON [pk_col].[column_id] = [fk_cols].[referenced_column_id] AND [pk_col].[object_id] = [fk_cols].[referenced_object_id] WHERE [fk].[object_id] IS NOT NULL) [fk] ON [fk].[tbl_name] = [o].[name] AND [idx_cols].[IndexColumns] LIKE '%' + [fk].[column_name] + '%' WHERE [o].[type] = 'U' -- user table AND [i].[index_id] = [s].[index_id] AND [s].[database_id] = DB_ID() AND [o].[name] = 'child' --AND i.name IN -- ( -- N'NCIX_Entry_COL_ET_accounting_period', -- N'NCIX_Entry_COL_ET_entry_type', -- N'NCIX_Entry_COL_ET_predefined_entry', -- N'NCIX_Entry_COL_ET_bmc_user_profile', -- N'NCIX_Entry_COL_ET_currency', -- N'NCIX_Entry_COL_ET_entry_address' -- ) ORDER BY [delta] DESC --ORDER BY user_seeks + user_scans + user_lookups DESC -- Order by reads --ORDER BY s.user_updates DESC OPTION -- Order by writes OPTION (RECOMPILE);