Knowledge is no fun, unless you share it!!! :)

Showing posts with label SqlServer. Show all posts
Showing posts with label SqlServer. Show all posts

Tuesday, 1 October 2013

Table Variables in SQL Server 2012 and differences with Temporary Tables

Table variable is handy feature of SQL Server which lets you define a variable as a table and then use it in SQL just like any other table.
Table variables were introduced in SQL Server 2000.

Temporary tables are also exists for same purpose in SQL-Server.
So there are some basic concept about usage of these two component of SQL-Server (Temporary Tables and Table Variables)

We can optimize our store procedure by repacing these components on the basis of there usages.
So today we will What is Table variables and what are the diffrence between Temporary Table and Table Variable.

SQL Server provides an variable known as table variable which is used to store data in a similar way as we store data in physical tables but with some limitations.
In SQL Server you can use temporary tables to store intermediate results. This is a common used technique to speed up query processing. Recently I came across a problem where the temporary tables were causing the performance degradation.
 
Table Variable:

You create a table variable the same way you create any other variable:
using the declare statement:

declare @TableVar table (CustomerID nchar(5) NOT NULL)

This declares a table variable named @TableVar that we can use in place of a temporary table. You can use a table variable for just about anything you'd use a regular table.
The following statements won't work however:

INSERT INTO table_variable
EXEC stored_procedure SELECT select_list INTO table_variable

We can write below piece of code inside store procedure:

DECLARE @ttable (idintIDENTITY,orderid int)
INSERT INTO @t(orderid)
SELECT a.OrderID FROM Database.TableA as a
INNER JOIN Database.TableB as b ON
a.ID = b.ID


For more diffreces you can go though the nice article written by Tejas Vashnav -
http://www.codeproject.com/Articles/415184/Table-Variable-V-S-Temporary-Table

Your suggestions is appriciated ! ! !
Next time we will learn about CTE (Common Table Expression) and it's usages.

Thursday, 26 September 2013

Temporary Table in SQL Server 2012 and It's Usage

Today i am going to tell about the Temporary tables. There are some myths about Temporary tables and there usages.
 
Many time we confuse while using this temporary tables.
What should be use Temporary table or Table variables?
But this topic i am going to cover in my next article.
 
Today we see how Temporary table make out life more easy!!
 
Usage of Temporary table is an effective mechanism available in all versions of SQL Server.
 
Temporary table:
It work like a regular table in that you can perform the operations select, insert and delete as for a regular table. If created inside a stored procedure they are destroyed upon completion of the stored procedure.
It stores in TempDB database.
 
There are two type of Temporary table availables -
  • Local Temporary Tables.
  • Global Temporary Tables.
Local Temporary Tables-
Local temporary tables are temporary tables that are available only to the session that created them. These tables are automatically destroyed at the termination of the procedure or session. They are specified with the prefix #, for example #table_name and these temp tables can be created with the same name in multiple windows.
It stores in TempDB database.
 
Global Temporary Table-
Global temporary tables are temporary tables that are available to all sessions and all users. They are dropped automatically when the last session using the temporary table has completed. They are specified with the prefix #, for example ##table_name.We can not create global temporary tables with same name in multiple window since it exists until we close all the sessions.
It also stores in TempDB database.
 
Physical location of Temporary table -
 
Whenever we create a temporary table, it goes to the Temporary folder of the tempdb database. tempdb -> temporary tables.
 
How to Drop Temporary Tables-
We can delete the temporary tables using the drop command as follows:
 
DROP TABLE #Temporary_Table
 

 Temporary tables are slighly diffrent from normal tables in following ways -
 
  • Temporary tables are always stores in TempDB database inside "Master Database". Tables are stores in there respective databases.
  • Temporary tables are implicitly dropped by system after killing all sessions. Tables have to drop explicitly by users.
Other functionality available in Temporary table-
 
It allows DDL operations i.e. Truncate, Alter Table.
It allows both clustered indexes and nonclustered indexes creations over the columns.
It can access in nested stored procedures.
It can participate in a transaction.
It writes to Log File.
It allows creation of statistics.
It can perform "Select Into" operation.
It can define globally.

 
Temporary tables have some limitations also that is we can not use it inside user define functions.
 
We will see about table variables and diffrence between Temporary table and table variable on my next article.
 
Feel free to shoot your ideas on this!!!
Thanks :)

Tuesday, 24 September 2013

DeadLock In SQL Server, Monitoring and Prevention

Deadlock is a nightmare for SQL DBA, since it stuck our database!!

So here i will explain what is Deadlock and how can we avoid it in realtime SQL situations.

A common issue with SQL Server is deadlocks. A deadlock occurs when two or more processes are waiting on the same resource and each process is waiting on the other process to complete before moving forward. When this situation occurs and there is no way for these processes to resolve the conflict, SQL Server will choose one of processes as the deadlock victim and rollback that process, so the other process or processes can move forward. 

In rare scenarios, I have heard of deadlocks caused by SQL Statements executing in parallel however I cannot reproduce it. Neither side is willing to step aside for the other processes. 

A database server should be able to service requests from a large number of concurrent users. When a database server is servicing requests from many clients, there is a strong possibility that conflicts will occur because different processes request access to the same resources at the same time. A conflict in which one process is waiting for another to release a resource is called a block.
A blocked process usually resolves itself when the first process releases the resource.

A more serious condition, called a deadlock or fatal embrace, occurs when the first process is also waiting on a resource held by the second process (see below). Each process is stuck waiting for the other to release a resource. Unless one process times out, the lock won’t clear itself.

When a deadlock occurs

These are the following conditions when a deadlock can occur:
  1. Mutual Exclusion - A resource is assigned to one process. Requests are delayed until the resources are released.
  2. Hold and wait - One process holds one resource and also waits for another.
  3. No preemption - Only a process can hold a resources when it's released from another process.
  4. Circular wait - The first transaction has a lock on some database object that the other transaction wants to access and vice versa, causing a deadlock by building a circle of dependencies.
 
Deadlock information can be captured in the SQL Server Error Log or by using Profiler / Server Side Trace.

Trace Flags

If you want to capture this information in the SQL Server Error Log you need to enable one or both of these trace flags.
  • 1204 - this provides information about the nodes involved in the deadlock
  • 1222 - returns deadlock information in an XML format
You can turn on each of these separately or turn them on together.

Extended Events:
SQL Server extended events are the light weight event driven (fired) data collection for SQL Servers. It is much beneficial in case of tracing in the busy servers. It’s fundamentally an advanced version of Profiler Trace. 

Profiler / Server Side Trace

Profiler works without the trace flags being turned on and there are three events that can be captured for deadlocks. Each of these events is in the Locks event class.
  • Deadlock graph - Occurs simultaneously with the Lock:Deadlock event class. The Deadlock Graph event class provides an XML description of the deadlock.
  • Lock: Deadlock - Indicates that two concurrent transactions have deadlocked each other by trying to obtain incompatible locks on resources that the other transaction owns.
  • Lock: Deadlock Chain - Is produced for each of the events leading up to the deadlock.

Although we cannot completely avoid deadlocks but they can be minimised by following the tips below:

  • Ensure the database is normalized properly because bad database design can increase the number of deadlocks to occur inside database.
  • Deadlocks can also occur if the resources are not acquired in some well-defined order because if all concurrent transactions access objects in the same order, deadlocks are less likely to occur. For example, if two concurrent transactions obtain a lock on the Department table and then on the Sales table, one transaction is blocked on the Department table until the other transaction is completed. After the first transaction commits or rolls back, the second continues, and a deadlock does not occur.
  • Do not allow users to input the data during transactions. Update all the data before the transaction begins.
  • Avoid cursors if possible because same transaction locking rules will apply to SELECT statement within a cursor definition that applies to any other SELECT statement. You can control the transaction locks for cursors definition SELECT statement by choosing the correct isolation and/or using the locking hints specified in the FROM clause. The locks are held until the current transaction for both cursors and independent SELECT statements ends. When SQL Server is running in auto commit mode, each individual SQL statement is a transaction and the locks are freed when the statement finishes. If SQL Server is running in explicit or implicit transaction mode, then the locks are held until the transaction is either committed or rolled back.
  • Reduce the time a transaction takes to complete by making sure you are not performing the same reads over and over again. If your application does need to read the same data more than once, cache it by storing it in a variable or an array, and then re-reading it from there, not from SQL Server. Reduce lock time. Try to develop your application so that it grabs locks at the latest possible time, and then releases them at the very earliest time.
  • If appropriate, control locks escalation by using the ROWLOCK or PAGLOCK because transaction locks in SQL Server consumes memory resources and when number of locks increases, memory decreases. If the percentage of memory used for transaction lock exceeds a certain threshold then SQL Server convert the fine-grained locks page or row) into a coarse-grained locks (table locks) which is also known as lock escalation. Lock escalation reduces the overall number of locks being held on the SQL Server instance, reducing the lock memory usage. While finer grained locks do consume more memory, they also can improve concurrency, as multiple queries can access unlocked rows.
  • Consider using the NOLOCK hint where possible because when you run the query against table in SQL Server default isolation level it will put a lock on table and any other query that will try to access the table will have to wait for the lock to be released. This is fine if your table is small but the things get slow if your table is big. A way to get around that is to add a NOLOCK hint to the query, which will override locking of the whole table and allow access to it to other queries. You have to be careful with using NOLOCK hint because it will allow for dirty reads for example if you execute the query with NOLOCK and the query runs for 30 seconds. Because the table is not locked, during these 30 seconds other queries may have added new rows that the query will not return or modified or deleted rows that were already read. It may also have read data from other queries that were uncommitted and could have been rolled back. So keep that in mind when using the NOLOCK hint.
You can see some more details on below link -
http://technet.microsoft.com/en-us/library/ms178104(v=sql.105).aspx

If you have any problems related to Deadlock just reach me by comments!!!
Your suggesions and comments are most welcome!!!

Thankyou :)

Wednesday, 11 September 2013

SQL-Server Join Advance Mechanism

SQL-SERVER Support Five type of joins:
  • Inner Join.
  • Left Outer Join.
  • Right Outer Join.
  • Full Outer Join.
  • Cross Join.

By choosing effective indexes and join strategies, the query optimizer builds an efficient plan to retrieve data from SQL queries.

Three join strategies are available to the query processor
  • Nested Loops Joins.
  • Merge Joins.
  • Hash Joins.

Nested-Loop Joins:
 
If the optimizer determines that a nested-loop join is the optimal join, it selects one table as the outer (first) table and the other as the inner table. When executing a nested-loop join, SQL Server scans the outer table row by row. For each row, it also scans the inner table, looking for matching rows. This join type is very efficient if one of the tables is small (or has been filtered so that it has only a few qualifying rows) and if the other table has an index on the column that joins the tables. The optimizer typically chooses the small table as its first input because this is the fastest method of executing the nest-loop algorithm.

For the nested-loop strategy to be effective, the inner table needs an index on the join column. This index means SQL Server doesn't need to scan the entire inner table; after accessing a row in the outer table, SQL Server can use the index on the join column to quickly find all matching rows in the inner table.

If the inner table doesn't have a useful index on the join column, the optimizer usually chooses a hash join strategy. However, if the join between the tables isn't based on equality, the optimizer chooses a nested-loop join, regardless of the tables' sizes and indexing schema.

Let's look at the following query on the tables:
SELECT C.CustomerName, O.OrderDate
FROM Customers C INNER JOIN
Orders O
ON C.CustomerID = O.CustomerID

The outer loop iterates through the rows in the Orders table. Note that because a clustered index contains the data, when the execution plan calls for a clustered index scan, the query processor scans the entire table. In the absence of a clustered index, this scan is called a table scan. For each row in the Orders table, the query processor uses clustered index seek, which scans a particular range of rows from a clustered index to seek a matching row in the Customers table because the join column CustomerID has a clustered index.

The query optimizer distinguishes among three variants of nested-loop joins.

A search that scans an entire table or index is a naïve nested-loop join.

A search that performs lookups in an index to fetch rows is an index nested-loop join.

When SQL Server builds an index as part of the query plan and destroys it when the query completes, you have a temporary index nested-loop join. If you notice the Query Analyzer using a temporary index nested-loop join for a common join, you might want to consider running the Index Tuning Wizard to determine whether you could benefit from adding an index to the base table.

Outlines:

  • It is very efficient if one of the tables is small (or has been filtered so that it has only a few qualifying rows) and if the other table has an index on the column that joins the tables. The optimizer typically chooses the small table as its first input because this is the fastest method of executing the nest-loop algorithm.
  •  The optimizer typically chooses the small table as its first input because this is the fastest method of executing the nest-loop algorithm.

Merge Joins:

If the optimizer decides that a merge join is optimal, the query execution scans two sorted inputs and merges them. For a merge join, the query processor sorts both inputs on the join column; if the two inputs to the join are already sorted on the join column (for example, if each has a clustered index on the join column), merge join is a logical choice. In other cases, if adequate memory is available, the optimizer might determine that sorting one input before joining inputs results in the most efficient join strategy.

If a one-to-many relationship exists between the inputs, SQL Server follows a series of steps for an inner join executed with a merge join strategy. First, it gets a row from each input, then compares the join columns of the rows. If the join columns match, SQL Server returns the requested columns from each row. If the columns don't match, SQL Server discards the row with the lower value and gets the next row from that input. SQL Server repeats these steps until it has processed all rows in both inputs, scanning both inputs only once.

To demonstrate a situation in which the optimizer will choose merge join, we inserted 10,000 rows into the Orders table. For each Order, we inserted five products into the OrderDetails table, resulting in 50,000 rows. Both Orders and OrderDetails have clustered indexes on the OrderID column. Then we executed the following query against the tables:

SELECT O.OrderID, O.OrderDate,OD.ProductID,OD.Quantity
FROM Orders O INNER JOIN OrderDetails OD
ON O.OrderID = OD.OrderID

SQL Server scans both the Orders table and the OrderDetails table. For each row in Orders, the matching rows in OrderDetails are merged.

Another case of merge join might occur if a many-to-many relationship exists between the inputs. If duplicate values exist in both inputs, the second input must be positioned to the point in the database where the first duplicate was found before the query processor can process the next duplicate from the first input. A temporary table stores the rows instead of discarding them. We can best explain this approach with a simple example:

SELECT Table1.Col1, Table1.Col2, Table2.Col3
FROM Table1 INNER MERGE JOIN Table2
ON Table1.Col1 = Table2.Col1

Note that in this example, we used a join hint (which we'll explain later) to force a merge join. With these small tables, the optimizer probably won't choose merge join.

Outlines:

  • If the two inputs to the join are already sorted on the join column (for example, if each has a clustered index on the join column), merge join is a logical choice.
  • Query processor sorts both inputs on the join column.
  • Another case of merge join might occur if a many-to-many relationship exists between the inputs

Hash Joins:

The third type of join is a hash join. The main reason why the SQL Server optimizer chooses the hash join algorithm is a lack of adequate indexes on the join columns. If the optimizer chooses a hash join, the execution plan involves building a hash table, which is like building a special index on the fly. The hash join strategy has two phases: build and probe. During the build phase, the query processor builds a hash table by scanning each value in the build input (usually the smaller table) and applying the hashing algorithm to the key. The hash table consists of linked lists called hash buckets. The hash function applied to each hash key in the build input determines the relevant hash bucket. During the probe phase, the query processor scans each row from the probe input (the second table) and computes the same hash value on the hash key to find any matches in the corresponding hash bucket.

Hash joins perform most efficiently when the tables differ significantly in size. While processing the query, SQL Server might determine that it chose the wrong table for the build input. In that case, a role reversal occurs, and the build input becomes the probe input and vice versa.

An example of a hash function is adding the ASCII values of the characters in the key field and extracting only the last few digits of the result. Another example is computing the modulo (percentage) of the key and a prime number. An important aspect of the hash algorithm is that, unlike regular index keys, the hash function can produce significantly shortened versions of the original keys. The hash function chosen generates an even distribution of the input rows in the hash buckets. These special hash indexes are efficient for finding exact matches (because the two join keys generate the same hash function result), but are useless for joining tables based on inequalities.

To demonstrate a situation in which the optimizer usually chooses a hash join, drop the constraints and both clustered indexes from the Orders and OrderDetails tables. Now execute the same query we ran in the merge join example:

SELECT O.OrderID, O.OrderDate,OD.ProductID, OD.Quantity
FROM Orders O INNER JOIN OrderDetails OD
ON O.OrderID = OD.OrderID

The Orders table is the best candidate for the build input because it's considerably smaller. The linked lists start with the function's possible results; in this case, there are only five. Linked to each bucket are records containing all the values the query will return from the build input table that correspond to the bucket. Applying the hash function to the join column of each build input record determines the correspondence. OrderID and OrderDate are the only columns you need from the build input (the Orders table), so these values are the only ones that stay in each record of the hash table.

SQL Server performs a table scan on the smaller table, Orders, which is the build input. Then it builds a hash table with the values that result from applying the hash function to each scanned row. SQL Server also performs a table scan on the probe—the OrderDetails table—and looks for the matching values in the hash table by applying to each scanned row the same formula that it used to build the hash table.

In some cases, your server might not have enough memory to hold the entire build input. In that case, SQL Server divides the hash table into multiple partitions and performs the join in separate steps, loading the relevant partition as needed. The hash join algorithm is very fast and efficient when proper indexes don't exist. This efficiency is an advantage when you want to run ad hoc queries without incurring the overhead of creating and dropping new indexes for only these queries.

Outlines:

  • The main reason why the SQL Server optimizer chooses the hash join algorithm is a lack of adequate indexes on the join columns.
  • The execution plan involves building a hash table, which is like building a special index on the fly.
  • hash join strategy has two phases: build and probe.
  • During the build phase, the query processor builds a hash table by scanning each value in the build input (usually the smaller table) and applying the hashing algorithm to the key.
  • During the probe phase, the query processor scans each row from the probe input (the second table) and computes the same hash value on the hash key to find any matches in the corresponding hash bucket.

Join Hints:

The query optimizer is very sophisticated, and in most cases, it chooses the best join strategy. However, in some situations, perhaps because of a lack of statistics or uneven data distributions, it might not make the right choice. When tuning query performance, experiment with different strategies on the same query to try to find a better strategy than the optimizer's choice. If you think that a better strategy is available, you can use join hints. Keep in mind, though, that after you add a join hint to the query, the query becomes static. You lose SQL Server's ability to process queries dynamically as a result of adding a new index, dropping an existing index, updating statistics, or modifying data in the tables.

The syntax for supplying join hints is

SELECT <select_list>
FROM <left_table_name>
<join_type> <join_hint>
JOIN <right_table_name>

The <join_type> can be LOOP, MERGE, or HASH. (A fourth hint, REMOTE, doesn't really control the join strategy as we discuss in this article, so we won't go into detail about it.) Note that you must use the ANSI join syntax to use a join hint. For example, to force a certain join strategy on a query that selects all orders and their details, use the process in Listing 3, page 40. To test the efficiency of a certain query, you can use SET STATISTICS TIME ON to show execution times, SET STATISTICS IO ON to show I/O costs, and SET SHOWPLAN_TEXT ON to show the execution plan.

Let's look at an example in which forcing a strategy that is different from the one the query processor chose might yield better performance. Suppose the Orders table has 10,000 orders and the OrderDetails table has five entries for each of those orders. Run the following query, which selects all orders, their products, and quantities:

SET SHOWPLAN_TEXT ON
GO
SELECT O.OrderID, O.OrderDate, OD.ProductID,OD.Quantity
FROM Orders O INNER JOIN OrderDetails OD
ON O.OrderID = OD.OrderID

The execution plan

Merge Join(Inner Join,
MERGE:(\[O\].\[OrderID\])=(\[OD\].\[OrderID\]),
RESIDUAL:(\[OD\].\[OrderID\]=\[O\].\[OrderID\]))
Clustered Index Scan
(OBJECT:(\[testdb\].\[dbo\].\[Orders\].
\[PK_Orders\] AS \[O\]), ORDERED)
Clustered Index Scan
(OBJECT:(\[testdb\].\[dbo\].\[OrderDetails\].
\[PK_OrderDetails\] AS \[OD\]), ORDERED)

shows that the query processor chose a merge join. Forcing different join strategies with join hints shows that merge join is the best choice for this case.

If you run the following query

SELECT O.OrderID, O.OrderDate, OD.ProductID,OD.Quantity
FROM Orders O INNER JOIN OrderDetails OD
ON O.OrderID = OD.OrderID
WHERE O.OrderID > 9900

the query processor chooses merge join again. But if you try a nested-loop join, you'll see that it yields considerably better performance:

SELECT O.OrderID, O.OrderDate, OD.ProductID,OD.Quantity
FROM Orders O INNER LOOP JOIN OrderDetails OD
ON O.OrderID = OD.OrderID
WHERE O.OrderID > 9900

You might use another hint to force the query processor to join tables in the order in which they're listed in the FROM clause. With no hint, the query optimizer decides the order of the joins on a cost-based estimation, regardless of their order in the SQL statement. To force the join order for a certain query, use the FORCE ORDER query hint. FORCE ORDER isn't a JOIN hint because it doesn't appear in the FROM clause. Alternatively, you can force the query processor to use your specified join order for all queries in the session level by using SET FORCEPLAN ON.

As a rule, avoid interfering with the query optimizer's decisions. The optimizer uses a variety of algorithms and in most cases, it comes up with the best plan. The new join techniques we discussed in this article are some of the improvements in SQL Server 7.0 that let you keep a normalized data model, accommodate VLDBs, and get your desired results faster.

Outlines:
  • When tuning query performance, experiment with different strategies on the same query to try to find a better strategy than the optimizer's choice. If you think that a better strategy is available, you can use join hints.
  • Keep in mind, though, that after you add a join hint to the query, the query becomes static.