I am very happy today because I get to share some rather interesting information on this particular topic for all of you for reducing (drastically in my case) the number of 114 errors with MS SQL Server 2000 (running SP4).
Yesterday I received several hundred of them (maybe thousands), and today I have received exactly 1 of them. I hope this works as well for everyone.
Like most of you, I want to tweak every little bit I can out of the performance of WinSyslog, so I started going back to basics, and reading articles on improving SQL performance (something I really haven't kept up with for about 4 years since I used SQL 7). And of course two of the most basic things in SQL definitely improved performance and removed almost all of the 114 errors.
Like most of you, I just cut and pasted the SQL statement for creating the necessary tables from the docs and created my table in SQL. I though "this is just a flat table, there's no real optimization needed other than a few indexes to improve reporting performance" - MAN WAS I WRONG.
The short and sweet is:
1. Create a NON-CLUSTERED index on the ID field - but be careful when doing this if you're using SQL Enterprise Manager since it always tries to create this as a CLUSTERED index by default.
2. Create a CLUSTERED index on the ReceivedAt field.
(see below for scripts)
For #2, in fact, you can create the clustered index on the ReceivedAt or DeviceReportedTime fields, depending on which one you usually run reports against. (Since I'm storing all my events in GMT locally to normalize the devices in different timezones, I usually use the ReceivedAt field to ensure I'm seeing things in a relatively sequential order).
The reason want clustered for the datetime fields is because clustered is a TON better than non-clustered for searching ranges (index seek instead of a table scan - and table scans are VERY costly). Since most of my reporting is done based on data/time ranges (e.g. yesterday, last night, this week), efficiency there is paramount.
- Code: Select all
CREATE CLUSTERED INDEX [idxClustReceivedAt_DEVMAPLE] ON [dbo].[SystemEvents]([ReceivedAt]) ON [PRIMARY]
You can only have one clustered index per table, so the index on the primary key (ID Field) must be non-clustered. This is perfectly okay as well since I don't think anyone uses the ID field other than for integrity or possibly sort order.
- Code: Select all
ALTER TABLE [dbo].[SystemEvents] ADD
CONSTRAINT [PK_nonClust_SystemEvents] PRIMARY KEY NONCLUSTERED
(
[ID]
) ON [PRIMARY]
I really hope this works as well for others as it has for me. I suspect (though I haven't tested) that creating the Primary Key field is the most significant method toward preventing the 114 events.
If you want to understand this better, a couple of great articles on primary keys and indexes:
http://www.sqlservercentral.com/columnists/awarren/worstpracticesnotusingprimarykeysandclusteredindex.asp
http://www.sqlservercentral.com/columnists/dharris/indexesanoverviewandmaintenanceforperformance.asp
http://www.sql-server-performance.com/gv_index_data_structures.asp


