I had known some tips for coding store procedure already.
Such as “don’t forget enable nocount”,”2 part names” ,”avoid prefix store procedure with sp_” and more…..
Today I will show you why don’t use sp_ as a prefix for store procedure and how to impact performance on the SQL server.
I refactored EF code instead of store procedure in our project in a few days ago.
I had completed this PR then push my last code to my branch on Stash and assigned reviewers.
My colleague(he is a native English speaker) added comment as “why usp_ and not sp_ like all other our store procedure”.
So I think I have to explain why.
Most people think sp_ stands for “store procedure”.
But in fact it means “special” store procedure in the master database.
If you use sp_MS_marksystemobject to marked it as a system object then the store procedure in master will execute in the context of the calling database.
In addition let’s look at a my simple performance test
create proc dbo.sp_dontdoit
as
begin
select AddressID,AddressLine1 from dbo.Address where AddressID=4
end
create proc dbo.usp_dontdoit
as
begin
select AddressID,AddressLine1 from dbo.Address where AddressID=4
end
I just executed 1000 times via SQLQuerystress for sp_ and usp_ and you saw result as below
Exec dbo.sp_dontdoit
Exec dbo.usp_dontdoit
Althought this adds a little overhead in performance but you have to know this problem.
Maybe you will say I just a luck or tools factor for prove different query performance.
Alright, I will track sp_ and usp_ with extended event on SQL2014 and you will find the same result.
CREATE EVENT SESSION [Compiles] ON SERVER
ADD EVENT sqlserver.query_post_compilation_showplan(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.query_pre_execution_showplan(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.sp_cache_hit(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.sp_cache_insert(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.sp_cache_miss(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.sp_cache_remove(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.sp_statement_completed(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.sp_statement_starting(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.sql_batch_completed(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.sql_batch_starting(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.sql_statement_completed(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.sql_statement_recompile(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.sql_statement_starting(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0))),
ADD EVENT sqlserver.uncached_sql_batch_statistics(
ACTION(sqlserver.client_app_name,sqlserver.sql_text)
WHERE ([sqlserver].[is_system]=(0)))
WITH (MAX_MEMORY=4096 KB,
EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY=30 SECONDS,
MAX_EVENT_SIZE=0 KB,
MEMORY_PARTITION_MODE=NONE,
TRACK_CAUSALITY=ON,
STARTUP_STATE=OFF)
GO
Exec dbo.usp_dontdoit twice
exec dbo.sp_dontdoit twice
This is why I should avoid sp_ as a prefix for store procedures.
Note:query each sp elapsed time via below tsql
SELECT
o.name AS 'object_name'
,p.execution_count
,p.total_worker_time AS 'total_worker_time(μs)'
,(p.total_worker_time/p.execution_count)*0.000001 AS 'avg_worker_time(s)'
,p.total_elapsed_time AS 'total_elapsed_time(μs)'
,(p.total_elapsed_time/p.execution_count)*0.000001 AS 'avg_elapsed_time(s)'
FROM sys.dm_exec_procedure_stats p
JOIN sys.objects o ON p.object_id = o.object_id;
GO
Reference:
CREATE PROCEDURE (Transact-SQL)
SR0016: Avoid using sp_ as a prefix for stored procedures
Impact of sp_ prefix on stored procedure performance
Rename All References to a Database Object
Is the sp_ prefix still a no-no?
[SQL SERVER][Memo]撰寫Stored Procedure小細節
The Performance Impact to Prefix Stored Procedures with sp_