Performance slow after optimise table on SQL Server

jordi79
Member Posts: 280
Hi,
I am using SQL Server 2005. I have a table that is used for reporting. This table is very big, and will probably grow to be the same size as a transaction table. This table has 29 keys. Out of which 1 is primary key, 20 is sorting keys and 9 are keys with sumindex. I have a report that takes about 3 hours to run based on this table. I am in the midst of trying to see what I can do to improve performance with this table. Some of the suggestions I gather from searches on this website are:
1) Do a table optimise on this table (This is the file --> DAtabase --> Information --> Tables --> Optimise)
--> I have done this, but after doing table optimise, I have found out that it takes longer for the report to complete. What use to take 3 hours, is now taking longer. It took 6 hours to run, and as of now, is still running. The report I am running only reads from this table. It does some writes too, but to some temporary tables like Excel buffer etc. But it only reads from this table, and writes to other temporary tables that it uses for it's internal process.
2) Set the non sumindex keys in the table to MaintainSQLIndex = FALSE
--> I have not done this yet. But will try later. I understand that keys that are used for sorting only, should set MaintainSQLIndex to false for performance. Does this include the primary key?
3) Rebuild Index regularly on this table (This is the rebuild index from SQL Management Studio)
--> I have not done this. But shouldn't optimise table be doing the same thing as this?
Any advice is welcome. thanks.
I am using SQL Server 2005. I have a table that is used for reporting. This table is very big, and will probably grow to be the same size as a transaction table. This table has 29 keys. Out of which 1 is primary key, 20 is sorting keys and 9 are keys with sumindex. I have a report that takes about 3 hours to run based on this table. I am in the midst of trying to see what I can do to improve performance with this table. Some of the suggestions I gather from searches on this website are:
1) Do a table optimise on this table (This is the file --> DAtabase --> Information --> Tables --> Optimise)
--> I have done this, but after doing table optimise, I have found out that it takes longer for the report to complete. What use to take 3 hours, is now taking longer. It took 6 hours to run, and as of now, is still running. The report I am running only reads from this table. It does some writes too, but to some temporary tables like Excel buffer etc. But it only reads from this table, and writes to other temporary tables that it uses for it's internal process.
2) Set the non sumindex keys in the table to MaintainSQLIndex = FALSE
--> I have not done this yet. But will try later. I understand that keys that are used for sorting only, should set MaintainSQLIndex to false for performance. Does this include the primary key?
3) Rebuild Index regularly on this table (This is the rebuild index from SQL Management Studio)
--> I have not done this. But shouldn't optimise table be doing the same thing as this?
Any advice is welcome. thanks.
0
Answers
-
ops... i have posted this in the wrong forum. how can I move this thread to SQL performance?0
-
Hi again,
my mistake. After optimise table, what used to take 3 hours is now taking 2 hours to run. Problem solved. The question now would be, how would one automate this task?0 -
Hi Jordi,
What version of Navision are you working on ?
About setting the property MaintainSQLIndex to False, it is not as easy that you can just set this property for all the secondary keys without SumIndexes. More important are the fields which are in the key, and for what purpose each key is used.
The report you mention, does that also update any records in this table ?K3 Business Solutions0 -
[Topic moved from 'NAV/Navision Classic Client' forum to 'SQL Performance' forum]
BTW: when you want to report spam or a post to move to another forum, just report the post (the red ! at the right of the post ; you need to be logged in to see it).
2) You can do that for the indexes that are not used in SQL.
This select finds them (if you find an index with user_seeks,user_scans,user_lookups all 0 it means it is not used). Before you run the query, you need to be sure that your database is online since some time to gather useful data.SELECT CONVERT([VARCHAR](80),PVT.TABLENAME) AS 'TABLENAME', CONVERT([VARCHAR](30),PVT.INDEXNAME) AS 'INDEXNAME', -- PVT.INDEX_ID, CASE WHEN (B.user_updates = 0) THEN (B.USER_SEEKS + B.USER_SCANS + B.USER_LOOKUPS) WHEN (B.USER_SEEKS + B.USER_SCANS + B.USER_LOOKUPS) < 200 THEN - B.user_updates ELSE ((B.USER_SEEKS + B.USER_SCANS + B.USER_LOOKUPS) / B.user_updates) END AS [UseFullNess], B.user_updates,B.USER_SEEKS,B.USER_SCANS, B.USER_LOOKUPS, B.last_user_seek, B.last_user_scan, B.last_user_lookup, CONVERT([VARCHAR](30),[1]) AS COL1, CONVERT([VARCHAR](30),[2]) AS COL2, CONVERT([VARCHAR](30),[3]) AS COL3, CONVERT([VARCHAR](30),[4]) AS COL4, CONVERT([VARCHAR](30),[5]) AS COL5, CONVERT([VARCHAR](30),[6]) AS COL6, CONVERT([VARCHAR](30),[7]) AS COL7, CONVERT([VARCHAR](30),[8]) AS COL8 FROM (SELECT A.NAME AS TABLENAME, A.OBJECT_ID, B.NAME AS INDEXNAME, B.INDEX_ID, D.NAME AS COLUMNNAME, C.KEY_ORDINAL FROM sys.objects A INNER JOIN sys.indexes B ON A.OBJECT_ID = B.OBJECT_ID INNER JOIN sys.index_columns C ON B.OBJECT_ID = C.OBJECT_ID AND B.INDEX_ID = C.INDEX_ID INNER JOIN sys.columns D ON C.OBJECT_ID = D.OBJECT_ID AND C.COLUMN_ID = D.COLUMN_ID WHERE A.TYPE <> 'S') P PIVOT (MIN(COLUMNNAME) FOR KEY_ORDINAL IN ( [1],[2],[3],[4],[5],[6],[7],[8] ) ) AS PVT INNER JOIN sys.dm_db_index_usage_stats B ON PVT.OBJECT_ID = B.OBJECT_ID AND PVT.INDEX_ID = B.INDEX_ID AND B.DATABASE_ID = DB_ID() WHERE ((B.user_updates > 100) OR (B.USER_SEEKS + B.USER_SCANS + B.USER_LOOKUPS > 100)) -- I will check them if the index is used a lot order by [UseFullNess]
Best not do that on the primary key (as most of the time, it is the clustered index).
3) index rebuild does the same thing, but you can give a certain fillfactor to be used (if you have a lot of reads and few writes, a 100% fillfactor can be ok, but it can slow down writes)
If you have a NAV version that is before 5.0SP1, than the optimize does more and I can give the advice to do a technical upgrade to a newer version.
If your table does not change too much, you can also try do to a index defrag. This is something that can be done online. It is mostly faster but it does not optimise the indexes so well. And afterwards, you need to update the sql server statistics of the table.Regards,Alain Krikilion
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!0 -
PeterVersteege wrote:Hi Jordi,
What version of Navision are you working on ?
About setting the property MaintainSQLIndex to False, it is not as easy that you can just set this property for all the secondary keys without SumIndexes. More important are the fields which are in the key, and for what purpose each key is used.
The report you mention, does that also update any records in this table ?
Hi Peter,
I am using ver 5.1. Actually after reading some of the posts made by the users in this forum I have a clearer picture on MaintainSQLIndex. It determines if you want SQL To created an index for this key in NAV. And if Yes, you can specify the fields SQL will use to create this Index in "SQLIndex" property in the "Key - Properties". In short, READ will be faster if SQL Index is created, but WRITE and INSERTS will be slower. And fields to be specified in "SQLIndex", must be carefully specified, with low selectivity.
It is amazing what you can learn if you spend a whole day reading this forums... \:D/
So far at the moment, the optimise table option has helped me.0 -
I still think that 2 hours to run a report, which only uses 1 table, is quite long. I still would advice you to reconsider if you really need all the current keys, because I imagine that filling the table even takes more time, and could become a problem in the upcoming months.
How many records does this table have now ?K3 Business Solutions0 -
this is actually a denormalised table from GL Entry table. it is denormalised to make reporting easier and to take the load of actual transaction tables when the report is run. This is similar to analysis views table in NAV. But it handles more dimensions compared to analysis views table. I am suggesting to partition the table into more records, and therefore having less key fields on this table. The structure of the current table:
1) Entry No. (Primary Key)
2) G/L Account No.
3) Posting Date
4) Dimension 1
5) Dimension 2
6) Dimension 3
7) Dimension 4
8) Dimension 5
9) Dimension 6
10) Dimension 7
11) Dimension 8
12) Dimension 9
13) Dimension 10
14) Dimension 11
15) Dimension 12
16) Dimension 13
17) Dimension 14
18) Dimension 15
19) Dimension 16
20) Dimension 17
21) Dimension 18
22) Dimension 19
23) Dimension 20
24) Amount
25) Field n++ (there are about additional 50++ fields here that store other information, but mostly they mirror the GLEntry table, so that we do not query the GLEntry table)
We have secondary keys with sumindex fields on "Amount". The keys are:
1) G/L Account No.,Posting Date,Dim Value 1,Dim Value 2,Dim Value 3,Dim Value 4,Dim Value 5
2) G/L Account No.,Posting Date,Dim Value 6,Dim Value 7,Dim Value 8,Dim Value 9,Dim Value 10
3) G/L Account No.,Posting Date,Dim Value 11,Dim Value 12,Dim Value 13,Dim Value 14,Dim Value 15
4) G/L Account No.,Posting Date,Dim Value 16,Dim Value 17,Dim Value 18,Dim Value 19,Dim Value 20
The user selects a group dimension to use for the report. So the user can only use 5 dimensions in a report at a time. I was thinking if I should split this table, so that Instead of 1 record having 20 dimension fields, to 4 records each having 5 dimension fields. But bear in mind, we have "Field n++". And with this we will be replicating the same information (which is "Field n++") across all the other fields. I was thinking of normalising this, so that "Field n++" can be stored in another table, but this would not be ideal for reporting. For reporting, a denormalised table would be better.
And with this, I need to maintain 1 secondary key with sumindex instead of 4 secondary keys with sumindex. I am not sure how will this affect performance. Any advice here?
I think I will need to come out with a proof of concept on this on how much time it can save on performance before proposing this change. Because we have developed a lot of reporting tools on this table, and changing the structure as such, is a big revamp.0 -
Maybe this could help you:
http://dynamicsuser.net/blogs/stryk/archive/2010/05/20/directions-emea-2010-nav-sql-performance-indexes.aspx
http://dynamicsuser.net/blogs/stryk/archive/2010/05/29/optimizing-sift-and-vsift.aspxJörg A. Stryk (MVP - Dynamics NAV)
NAV/SQL Performance Optimization & Troubleshooting
STRYK System Improvement
The Blog - The Book - The Tool0
Categories
- All Categories
- 73 General
- 73 Announcements
- 66.6K Microsoft Dynamics NAV
- 18.7K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 617 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 320 Dynamics CRM
- 111 Dynamics GP
- 10 Dynamics SL
- 1.5K Other
- 990 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 35 Design Patterns (General & Best Practices)
- 1 Architectural Patterns
- 10 Design Patterns
- 5 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1.1K General Chat
- 1.6K Website
- 83 Testing
- 1.2K Download section
- 23 How Tos section
- 252 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions