== Nov 9 update ==
In some cases we got integer overflow when running this query. So the table definitions in the query have now changed from using int to bigint to avoid this.
== end of update ==
The query below combines these three queries into one:Index Usage QueryRecent Bocking HistoryTable Information Query
It can be used to just see the number of records in each table. But also by just changing "ORDER BY", it can be used to see which index cause most blocking / wait time / updates or locks. Or to compare Index Updates with Index Reads to get an idea of cost versus benefit for each index for the purpose of index tuning.
So in short, one query gives you: - Index / Table Information - Index usage (benefits and costs information for each index) - Index locks, blocks, wait time and updates per read (cost/benefit).
The query must be run in your NAV database. It will create a table called z_IUQ2_Temp_Index_Keys and use various Dynamic Management Views to collect information for each index into this table. First time you run it, or if you want to refresh data, you must run the whole query which may take up to a minute of two for each company in the database. After that if you just want to change sorting / get the results again, then you only need to run the last part of the query, beginning with:
-- Select results
The last lines suggest various "ORDER BY"s that might be useful to enable instead of the default one, which is by Table Name.
Lars Lohndorf-Larsen (Lohndorf )
Microsoft Dynamics UK
Microsoft Customer Service and Support (CSS) EMEA
These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.
--use NavisionDatabase
IF
NULL
DROP
;
-- Generate list of indexes with key list
create
(
[l1] [bigint]
NULL,
[F_Obj_ID] [bigint]
[F_Schema_Name] [nvarchar]
[F_Table_Name] [nvarchar]
[F_Row_Count] [bigint]
[F_Reserved] [bigint]
[F_Data] [bigint]
[F_Index_Size] [bigint]
[F_UnUsed] [bigint]
[F_Index_Name] [nvarchar]
[F_Index_ID] [bigint]
[F_Column_Name] [nvarchar]
[F_User_Updates] [bigint]
[F_User_Reads] [bigint]
[F_Locks] [bigint]
[F_Blocks] [bigint]
[F_Block_Wait_Time] [bigint]
[F_Last_Used] [datetime]
[F_Index_Type] [nvarchar]
[F_Index_Column_ID] [bigint]
[F_Last_Seek] [datetime]
[F_Last_Scan] [datetime]
[F_Last_Lookup] [datetime]
[Index_Key_List] [nvarchar]
NULL )
)
go
CREATE
[z_IUQ2_Temp_Index_Keys]
ASC
insert
z_IUQ2_Temp_Index_Keys
SELECT
,
a1
a3
a2
, (
-- Index Description
SI
index_col
),
-- Index Stats
US
-- Index blocks
IStats
-- Dates
case
when
last_user_seek
last_user_scan
else
last_user_lookup
end
SIC
''
FROM
ps
SUM
CASE
WHEN
row_count
ELSE
0
END
used
GROUP
LEFT
it
INNER
WHERE
) INNER
) inner
inner
) left
left
()) left
())
'IT'
order
desc
-- Populate key string
declare
for select
select
for
Index_Key_List
int declare
set
open
IndexCursor
on fetch
fetch
@IndID
while
begin set
', '
from
where
ORDER
F_Index_Column_ID
update
@KeyString
close
deallocate
IndexCursor go
-- clean up table to one line per index
delete
1 go
[F_Table_Name] TableName
[F_Row_Count] No_Of_Records
[F_Data] Data_Size
[F_Index_Size] Index_Size
[F_Index_Name] Index_Name
[F_User_Updates] Index_Updates
[F_User_Reads] Index_Reads
F_User_Updates
F_User_Reads
[F_Locks] Locks
[F_Blocks] Blocks
[F_Block_Wait_Time] Block_Wait_Time
[F_Last_Used] Index_Last_Used
[F_Index_Type] Index_Type
[Index_Key_List] Index_Fields
--order by F_Row_Count desc, F_Table_Name, [F_Index_ID]
--order by F_User_Updates desc
--order by Blocks desc
--order by Block_Wait_Time desc
--order by Updates_Per_Read desc
F_Table_Name