I was using the sp_helptext very frequently to get the definition of an object.
Here is another easy way to get the definition of an object
SELECT OBJECT_DEFINITION(object_id) FROM sys.objects WHERE type='V'
You can use the, ALTER in the result set of the above query by using the REPLACE.
In the where condition you can specify the Procedure(P) or Functions(FN) as well.
Monday, April 11, 2011
Monday, April 4, 2011
Difference between NEWSEQUENTIALID() and NEWID()
In this article, we will be looking at the Difference between NEWSEQUENTIALID() and NEWID() and How NEWSEQUENTIALID() is generated.
NEWSEQUENTIALID() generates the unique identifier values sequentially.
Whereas NEWID() generates the unique identifier values randomly.
NEWSEQUENTIALID() function creates the GUIDs greater than the previously generated GUIDs, since the last restart of the system, because after restarting the system the next NEWSEQUENTIALID can be started from the lower range.
Both NEWID() and NEWSEQUENTIALID() are globally unique. Starting of NEWSEQUENTIALID after the restart of the computer does not affect its globally uniqueness.
NEWSEQUENTIALID() uses the default constraint, and it can't be used in SELECT or SET queries like NEWID().
The following query SELECT NEWSEQUENTIALID() will generate error
The newsequentialid() built-in function can only be used in a DEFAULT expression for a column of type 'uniqueidentifier' in a CREATE TABLE or ALTER TABLE statement. It cannot be combined with other operators to form a complex scalar expression.
This will also generate the similar error
declare @varunique UNIQUEIDENTIFIER
SET @varunique=NEWSEQUENTIALID()
SELECT @varunique
Msg 302, Level 16, State 0, Line 3
The newsequentialid() built-in function can only be used in a DEFAULT expression for a column of type 'uniqueidentifier' in a CREATE TABLE or ALTER TABLE statement. It cannot be combined with other operators to form a complex scalar expression.
while if you use
SELECT NEWID()
OR
declare @varunique UNIQUEIDENTIFIER
SET @varunique=NEWSEQUENTIALID()
SELECT @varunique
No error will be produced and guid will be returned.
NEWID() is not good for performance because it is generated randomly so that it increases the page splits in the indexes.
NEWSEQUENTIALID() can be used to generate GUIDs to reduce page contention at the leaf level of indexes.
Each GUID generated by using NEWSEQUENTIALID() is unique on that computer.
GUIDs generated by using NEWSEQUENTIALID() are unique across multiple computers only if the source computer has a network card.
NEWSEQUENTIALID() returns the value that includes the MAC of the NIC of the system. If the system has the network card, then it is guaranteed that the GUID generated using NEWSEQUENTIALID() will globally unique across the servers.
If the NEWSEQUENTIALID() used on a computer that doesn't have NIC, the values generated using NEWSEQUENTIALID() are not guaranteed to be unique across the servers, it will be unique only for that system.
Internally NEWSEQUENTIALID() usses a Windows API called UuidCreateSequential(), which generates the value based on the NIC's MAC address and an internal hardware timestamp.
Here you can see the Newsequentialid (Histrory/Benefits and Implementation)
NEWSEQUENTIALID() generates the unique identifier values sequentially.
Whereas NEWID() generates the unique identifier values randomly.
NEWSEQUENTIALID() function creates the GUIDs greater than the previously generated GUIDs, since the last restart of the system, because after restarting the system the next NEWSEQUENTIALID can be started from the lower range.
Both NEWID() and NEWSEQUENTIALID() are globally unique. Starting of NEWSEQUENTIALID after the restart of the computer does not affect its globally uniqueness.
NEWSEQUENTIALID() uses the default constraint, and it can't be used in SELECT or SET queries like NEWID().
The following query SELECT NEWSEQUENTIALID() will generate error
The newsequentialid() built-in function can only be used in a DEFAULT expression for a column of type 'uniqueidentifier' in a CREATE TABLE or ALTER TABLE statement. It cannot be combined with other operators to form a complex scalar expression.
This will also generate the similar error
declare @varunique UNIQUEIDENTIFIER
SET @varunique=NEWSEQUENTIALID()
SELECT @varunique
Msg 302, Level 16, State 0, Line 3
The newsequentialid() built-in function can only be used in a DEFAULT expression for a column of type 'uniqueidentifier' in a CREATE TABLE or ALTER TABLE statement. It cannot be combined with other operators to form a complex scalar expression.
while if you use
SELECT NEWID()
OR
declare @varunique UNIQUEIDENTIFIER
SET @varunique=NEWSEQUENTIALID()
SELECT @varunique
No error will be produced and guid will be returned.
NEWID() is not good for performance because it is generated randomly so that it increases the page splits in the indexes.
NEWSEQUENTIALID() can be used to generate GUIDs to reduce page contention at the leaf level of indexes.
Each GUID generated by using NEWSEQUENTIALID() is unique on that computer.
GUIDs generated by using NEWSEQUENTIALID() are unique across multiple computers only if the source computer has a network card.
NEWSEQUENTIALID() returns the value that includes the MAC of the NIC of the system. If the system has the network card, then it is guaranteed that the GUID generated using NEWSEQUENTIALID() will globally unique across the servers.
If the NEWSEQUENTIALID() used on a computer that doesn't have NIC, the values generated using NEWSEQUENTIALID() are not guaranteed to be unique across the servers, it will be unique only for that system.
Internally NEWSEQUENTIALID() usses a Windows API called UuidCreateSequential(), which generates the value based on the NIC's MAC address and an internal hardware timestamp.
Here you can see the Newsequentialid (Histrory/Benefits and Implementation)
Tuesday, March 22, 2011
Find Created date and Modified date of Database objects
This script will return the objects in sql server database with modified and created date.
However you can change the order by clause as well as the Where clause according to your requirements
SELECT sys.schemas.name + '.' + sys.objects.name,
create_date,
modify_date
FROM sys.objects
INNER JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id
WHERE type = 'P'
OR type = 'U'
OR type = 'FN'
OR type = 'V'
ORDER BY modify_date DESC
However you can change the order by clause as well as the Where clause according to your requirements
SELECT sys.schemas.name + '.' + sys.objects.name,
create_date,
modify_date
FROM sys.objects
INNER JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id
WHERE type = 'P'
OR type = 'U'
OR type = 'FN'
OR type = 'V'
ORDER BY modify_date DESC
Thursday, March 10, 2011
The newsequentialid() built-in function can only be used in a DEFAULT expression
Msg 302, Level 16, State 0, Line 3
The newsequentialid() built-in function can only be used in a DEFAULT expression for a column of type 'uniqueidentifier' in a CREATE TABLE or ALTER TABLE statement. It cannot be combined with other operators to form a complex scalar expression.
This error occurs when we try to use the NEWSEQUENTIALID() function in the SQL statements or in SET statements. e.g.
SELECT NEWSEQUENTIALID()
OR
declare @varunique UNIQUEIDENTIFIER
SET @varunique=NEWSEQUENTIALID()
SELECT @varunique
OR
INSERT INTO AA(id, name) VALUES(NEWSEQUENTIALID(),'abc')
The NEWSEQUENTIALID() built-in function can only be used in a DEFAULT expression for a column of type 'uniqueidentifier' in a CREATE TABLE or ALTER TABLE statement. It cannot be combined with other operators to form a complex scalar expression.
The newsequentialid() built-in function can only be used in a DEFAULT expression for a column of type 'uniqueidentifier' in a CREATE TABLE or ALTER TABLE statement. It cannot be combined with other operators to form a complex scalar expression.
This error occurs when we try to use the NEWSEQUENTIALID() function in the SQL statements or in SET statements. e.g.
SELECT NEWSEQUENTIALID()
OR
declare @varunique UNIQUEIDENTIFIER
SET @varunique=NEWSEQUENTIALID()
SELECT @varunique
OR
INSERT INTO AA(id, name) VALUES(NEWSEQUENTIALID(),'abc')
The NEWSEQUENTIALID() built-in function can only be used in a DEFAULT expression for a column of type 'uniqueidentifier' in a CREATE TABLE or ALTER TABLE statement. It cannot be combined with other operators to form a complex scalar expression.
Monday, March 7, 2011
SQL Server Interview Questions (Part 2)
Few days back, i went for an interview , following questions were asked
- How to Performance Tune a Stored Procedure?
- Type of Triggers?
- How to get the old value of a field from a trigger when updating a table?
- What is the difference between horizontal partition and vertical partition?
- if we have three parameters in the where condition (query has the joins with two or more tables table1.filed1=4 and table2.field2=5 and table3.field3=1)
what will be the Order of execution of the where condition
Which condition would be executed first i.e. field1 or field2 or field3? - What are the disadvantages of the cursors?
- A stored procedure has cursors in it, how we can eliminate the cursors?
- What is the difference between temporary table and table variable?
- How to restore the Differential Backup?
- What are Backup Types and difference between them?
- What are Replication Types, What is snapshot replication?
- What is the difference between Replication and Mirroring?
- Can a sub report in Crystal Reports can have another sub report?
- What is log shipping?
- Should we normalize the Database on more than 3rd Normal form?
Tuesday, February 15, 2011
What is Parameter Sniffing, How it can affect the Performance, and What is the Solution
|
| Let us try to answer these questions, |
| Whenever a stored procedure is executed for the first time, its execution plan is created. An execution plan for a stored procedure is created the first time a stored procedure is executed. When the SQL SERVER Database engine compiles a stored procedure it looks at the parameters being passed to the stored procedure and then creates an execution plan based on these parameters. The process of looking at parameter values when compiling a stored procedure is called "Parameter sniffing". Sometimes Parameter sniffing can lead to inefficient execution plans, especially when a stored procedure is called with parameter values that have different cardinality. |
| Parameter sniffing can be considered a plus to the performance of the system, but in those cases where it's not, various mechanisms can be used to avoid it. One of the simplest is to use local variables. You can also use the OPTIMIZE FOR query hint or the WITH RECOMPILE query hint. In extreme cases you can force specific execution plans onto procedures. |
| We can also say that Parameter sniffing is a process that occurs when executing a stored procedure for the first time that allows SQL Server to build an effective query plan. Normally that is a good thing, but in some cases can actually hurt performance of the query. |
According to the white paper Batch Compilation, Recompilation, and Plan Caching Issues in SQL Server 2005 Published in the Microsoft Site: |
| "Parameter sniffing" refers to a process whereby SQL Server's execution environment "sniffs" the current parameter values during compilation or recompilation, and passes it along to the query optimizer so that they can be used to generate potentially faster query execution plans. The word "current" refers to the parameter values present in the statement call that caused a compilation or a recompilation" |
When a SP is not in the procedure cache, when it is executed the query optimizer needs to compile the SP to create an execution plan. In order to do this the query optimizer needs to look at the parameters that are passed and the body of the SP to determine the best method to go about processing the SP. When the query optimizer looks at the SP's parameters, to help determine how to optimize the execution of the SP, it is known as parameter sniffing. |
| Before I show you with an example about parameter sniffing, you need to know that the query execution plan generated by the SQL Server depends on lot of factors; parameter sniffing is just one of them. So the execution plan I show here might be different from the execution plan that you will generate. |
| Let's look at the following code |
USE AdventureWorks |
| GO |
CREATE PROCEDURE GetCustOrders (@FirstCust int, @LastCust int) |
| AS |
| SELECT * FROM Sales.SalesOrderHeader |
| WHERE CustomerID between @FirstCust and @LastCust; |
This procedure GetCustOrders accepts two parameters @FirstCust int, @LastCust int . These parameters are passed in the where clause of the query to get the customer orders. Now look at the execution plan of the procedure by execution this procedure by passing different parameters. |
USE AdventureWorks |
| GO |
| DBCC FREEPROCCACHE |
| EXEC GetCustOrders 1, 1000 |
I had used the statement DBCC FREEPROCCACHE to clear the procedure cache so that query optimizer should make a new plan for this execution instead of using any existing one. |
| Look at the |
| Actual number of Rows 31465 and |
| Estimated number of Rows 31465 |
| Here you can see that query optimizer performed a Clustered Index scan operation to get the records. |
| Now execute EXEC GetCustOrders 600,610 and see the execution plan |
| It uses the Clustered index scan for this operation as well, because this plan was present in the procedure cache. |
| Check the number of actual rows and estimated rows, |
| Actual number of Rows 31465 |
| Estimated number of Rows 31465 |
| Note the in both cases the actual and estimated number of rows are same. |
| Now clear the procedure cache and execute the procedure with smaller values |
DBCC FREEPROCCACHE |
| EXEC GetCustOrders600,610 |
| Exmaince the actual number of rows and estimated number of rows, they are different now, because optimizer created a new plane for this |
Query optimizer performed the seek operation. This means that by passing the smaller range of values , you can get the Index Seek operation, depending on your execution. If you execute the procedure with smaller values first and then execute the procedure with larger values. Then you can get Index seek for both of the executions. |
| The first compile of the Procedure generates the execution plan depending on the the parameters passed to the procedure and that plan is kept in the procedure cache for use of future executions of that procedure. |
| How to eliminate parameter sniffing? |
There are three methods to avoid parameter sniffing, |
|
By using Local variables |
| Parameter sniffing can be disabled by using the local variables in the stored procedure. |
CREATE PROCEDURE GetCustOrders (@FirstCustint, @LastCustint) |
AS |
DECLARE @FC int/td> |
| DECLARE @LC int |
| SET @FC = @FirstCust |
| SET @LC = @LastCust |
| SELECT * FROM Sales.SalesOrderHeader |
| WHERE CustomerID BETWEEN @FC AND @LC |
You can create two local variables @FC AND @LC that takes the values from parameters of the stored procedure and then pass those values to the query. In this way the actual values of the parameters are no longer contained in the BETWEEN clause in the SELECT statement, instead only those local variables are present. |
| This method of removing the parameter sniffing problem doesn’t mean you will get a best plan for each execution of the SP |
By using Recompile |
| Creating a stored procedure that specifies the WITH RECOMPILE option in its definition indicates that SQL Server does not cache a plan for this stored procedure; the stored procedure is recompiled each time it is executed. Use the WITH RECOMPILE option when stored procedures take parameters whose values differ widely between executions of the stored procedure |
| USEAdventureWorks |
GO |
CREATE PROCEDURE GetCustOrders(@FirstCust int,@LastCust int) |
| WITH RECOMPILE |
| AS |
| SELECT*FROMSales.SalesOrderHeader |
| WHERECustomerIDbetween@FirstCustand@LastCust ; |
By using Optimize For |
| Instructs the query optimizer to use statistical data instead of the initial values for all local variables when the query is compiled and optimized, including parameters created with forced parameterization |
| CREATE PROCEDUREGetCustOrders(@FirstCustint,@LastCustint) |
| WITH RECOMPILE |
| AS |
| SELECT*FROMSales.SalesOrderHeader |
| WHERECustomerID between @FirstCustand @LastCust |
| OPTION (OPTIMIZE FOR (@FirstCust UNKNOWN,@LastCust UNKNOWN)); |
| go |
| You can read more about Query Hints from msdn |
Tuesday, February 8, 2011
SQL Load Generator
A really nice tool for Load testing on SQL Server. SQL Load Generator is used to generate a load simulating several different users. It is is used to run multiple concurrent queries against SQL Server. The user can choose the number of concurrent queries to run, provide different queries, choose SQL or domain accounts, and provide application name settings.
read more or if you want to download SQL Load Generator you need to go on codeplex SQL Load Generator
read more or if you want to download SQL Load Generator you need to go on codeplex SQL Load Generator
Subscribe to:
Posts (Atom)





