Its true. Does not look so?
Before few days while I was struggling with our huge database for management and performance issues, I decided to write a series which will deal with creating high performant web application. The motto is to share my ideas which I developed and found useful in achieving better performance during course of various project I worked on.
The main platform I am using is ASP.NET/C#/SqlServer Trio. But the ideas equally apply to any web development platform and tool.
Problem Defined :
Creating Multiple Clustered Index on Sql Server Table
Why it is needed ?
Our one table is very big (contains around 30 million records currently) and having more than 80 columns (of course not normalized since normalization will force joining for most of the reports which does cut performance to a great extent). We have multiple reports to come from the same table. Some time the report is as short as 10 records.
When we query for some 10 records in this big table, we face performance issue. The query executes in 2-10 minutes.
Initial Solution
So first we created one clustered index on this table which contains two columns. And come out with very fast performing queries which now take 0-1 seconds instead of 2-10 minutes for the same set of records.
But our joy was only for short span. Since we had 15 more reports having different key columns. Multiple indices are possible only through non clustered index(logically ordering of records). We can normally create only one clustered index ( physical ordering of records). The clustered indices used to be much more faster than non clustered once due to obvious reasons. And we need clustered one do get maximum performance.
Sql Server does not allow us to create multiple clustered indices.
Final Solution
We thought and found the way out of this issue as following. And it really worked.
First we created multiple views on the table as was required by our various reports.
Then we added Unique Clustered Indices to these views based on the key fields of our reports. And finally we wrote queries on the table (not on view). The indices we have created on views are actually associated with the table and since they are clustered they give same performance as a clustered index on the table.
And thats what we wanted. Now all our reports are performing very well and fast enough to satisfy us.
All Suggestions/Feedback/Queries highly appreciated.
Thursday, December 18, 2008
Tuesday, December 16, 2008
Sql Server - Tips & Tricks
Requirement : Creating Identity Column on a table which already contains data.
Need: There may be various reasons. One possible reason could be to create an Index on view of a table.
Problem Described: In one of our project we have a table which contains around 30 million records. There are different reports where we display the records from the same table. Suppose I have ten different reports which uses different columns from the table. In order for better performance for such heavy table I must create appropriate indexes. But if we create ten different indexes including multiple columns it will again become performance bottleneck.
Solution Approached:
So we decided to create multiple VIEWs based on our reports on the same table and decided to create unique clustered indexes for those views. Since clustered indexes store data physically and will update the index on change in base table. It will boost application performance. But here comes another hurdle. Since our table does not contain a primary key as well as no unique column was introduced ( when that table was created ), it was not possible to create index on VIEWs since it requires unique column or key.
It is possible to alter table and add one more column as identity column but it will internally create another table and will move all records from current table to new table with values in identity column and finally delete the previous table. It was not possible because our table contains huge amount of data and we had less disk space for the table to be copied
For that the solution to used is as follows.
1. Alter the table(eg mytable) to add one extra column (eg newintcolumn) which should of type int.
2. use the following code to populate this column for existing data.
declare @cnt int
set @cnt = 1
update mytable set newintcolumn = @cnt , @cnt = @cnt+1
3. Alter the newintcolumn to identity.
This has solved my problem.
All Suggestion/Feedback highly appreciated.
Need: There may be various reasons. One possible reason could be to create an Index on view of a table.
Problem Described: In one of our project we have a table which contains around 30 million records. There are different reports where we display the records from the same table. Suppose I have ten different reports which uses different columns from the table. In order for better performance for such heavy table I must create appropriate indexes. But if we create ten different indexes including multiple columns it will again become performance bottleneck.
Solution Approached:
So we decided to create multiple VIEWs based on our reports on the same table and decided to create unique clustered indexes for those views. Since clustered indexes store data physically and will update the index on change in base table. It will boost application performance. But here comes another hurdle. Since our table does not contain a primary key as well as no unique column was introduced ( when that table was created ), it was not possible to create index on VIEWs since it requires unique column or key.
It is possible to alter table and add one more column as identity column but it will internally create another table and will move all records from current table to new table with values in identity column and finally delete the previous table. It was not possible because our table contains huge amount of data and we had less disk space for the table to be copied
For that the solution to used is as follows.
1. Alter the table(eg mytable) to add one extra column (eg newintcolumn) which should of type int.
2. use the following code to populate this column for existing data.
declare @cnt int
set @cnt = 1
update mytable set newintcolumn = @cnt , @cnt = @cnt+1
3. Alter the newintcolumn to identity.
This has solved my problem.
All Suggestion/Feedback highly appreciated.
Subscribe to:
Posts (Atom)
