SQL Server Best Practices
Recently was discussing with a colleague of mine as to the best practices in SQL. So this post is dedicated to that chat. The first thing we discussed about is the usage of NOLOCK's for tables in non highly transactional based databases with a wide user audience. Now the question of dirty reads does come to mind but at the end of the day the Read Uncommited transaction allows multiple end users to query the underlying table. NOLOCK is nothing more than a table hint that allows the query to be performed in a read uncommited fashion but is still a great practice to follow even while creating views. I have been using NOLOCK's for a large period of time (and sometimes implement it out of habit for my views i.e. SELECT C1,C2 FROM V1 (NOLOCK) as well which does not make any sense but is more of a force of habit except for my last post where I removed it on purpose) but I recently came across another table hint called READPAST but I am strictly avoiding this topic as this prevents the end user from reading locked rows as well. Another thing we discussed about was the usage of transactions within stored procedures. It is a good practice for SQL developers to always wrap SP's within transactions. Creation of an SP should have a BEGIN TRAN statement. The reason is quite simple Dr. Watson, you would want all the transactions that take place within the SP to be commited at one point in time. But there are exceptions to this practice and let us say that you are pulling information from table X to table Y and then going to update X or Y based on some logic. We would want the inserts to go ahead as planned and would not want to roll back the inserts unless it is a very small data load (roughly a couple of 100 records). The transaction wrapping allows us to follow the "ACI" of the ACID properties of an RDBMS. The next aspect to follow is the usage of ANSI standard SQL while writing basic standard SQL statements. I totally disagreed with this aspect, first and foremost using the standard t-sql everywhere is not going to downgrade the performance of your SQL. Example:
The performance in SQL server is going to be the same.... I do agree from a readability perspective that the ANSI standard is better but I am not going to support a standard just because the readability is a bit better. I do however use t-sql on a regular basis for majority of my queries but in case if the queries is to be made available to productionand the users are more familiar with a specific standard then I would definitely go ahead with the standard that is followed. Usage of cursors is not good..... I agree but it cannot be avoided everywhere and besides I think CURSORS even though non performant does have a lot of benefits.
Benefits:
I have a table TableCountry on which I have no primary keys on. I created a view on top of this called dbo.temp_view and I have another view called Test.temp_view with the same underlying SQL with a slight difference while creating the views as follows:
CREATE VIEW [dbo].Temp_View AS
SELECT Country,Margin FROM [dbo].[TableCountry]
CREATE VIEW [Test].Temp_View WITH SCHEMABINDING AS
SELECT Country,Margin FROM [dbo].[TableCountry]
The next step was for me to create a clustered index on top of the view [Test].Temp_View as follows:
CREATE UNIQUE CLUSTERED INDEX idx_temp_view ON [Test].Temp_View (Country)
Now let me execute the following queries in the order defined below:
SET SHOWPLAN_ALL ON
SELECT Country FROM [dbo].[temp_view]
SELECT Country FROM [Test].Temp_View WITH (NOEXPAND)
Now if you check out the result plan you will notice that the second query utilizes a CLUSTERED INDEX SCAN VS the TABLE SCAN used for the first query. Also the underlying CPU cost for the second is much lesser (as it is targeting a fixed segment on the page) rather than the page itself. Indexed views are really beneficial when you are targeting large tables using views and dont want the underlying MACRO EXPANSION to happen. But there is a cost of maintaining the index for the view (Speed VS Cost) which is something where one has to carefully consider while working with large OLTP systems.
The performance in SQL server is going to be the same.... I do agree from a readability perspective that the ANSI standard is better but I am not going to support a standard just because the readability is a bit better. I do however use t-sql on a regular basis for majority of my queries but in case if the queries is to be made available to productionand the users are more familiar with a specific standard then I would definitely go ahead with the standard that is followed. Usage of cursors is not good..... I agree but it cannot be avoided everywhere and besides I think CURSORS even though non performant does have a lot of benefits.
Benefits:
- Iterative looping (start from i and go on to n-1 once)
- Ensuring that every row is taken into consideration
- More hands on with the row cell than set based operations
- Primary Keys are not required in the underlying data set or for that matter even generating a ROW_NUMBER() for the dataset
I have a table TableCountry on which I have no primary keys on. I created a view on top of this called dbo.temp_view and I have another view called Test.temp_view with the same underlying SQL with a slight difference while creating the views as follows:
CREATE VIEW [dbo].Temp_View AS
SELECT Country,Margin FROM [dbo].[TableCountry]
CREATE VIEW [Test].Temp_View WITH SCHEMABINDING AS
SELECT Country,Margin FROM [dbo].[TableCountry]
The next step was for me to create a clustered index on top of the view [Test].Temp_View as follows:
CREATE UNIQUE CLUSTERED INDEX idx_temp_view ON [Test].Temp_View (Country)
Now let me execute the following queries in the order defined below:
SET SHOWPLAN_ALL ON
SELECT Country FROM [dbo].[temp_view]
SELECT Country FROM [Test].Temp_View WITH (NOEXPAND)
Now if you check out the result plan you will notice that the second query utilizes a CLUSTERED INDEX SCAN VS the TABLE SCAN used for the first query. Also the underlying CPU cost for the second is much lesser (as it is targeting a fixed segment on the page) rather than the page itself. Indexed views are really beneficial when you are targeting large tables using views and dont want the underlying MACRO EXPANSION to happen. But there is a cost of maintaining the index for the view (Speed VS Cost) which is something where one has to carefully consider while working with large OLTP systems.
Comments