Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Podczas wykonywania procedury składowanej, jaka jest korzyść z używania CommandType.StoredProcedure w porównaniu z używaniem CommandType.Text?

Zgodnie z testami w tym wpisie na blogu, SQL Server dokona parametryzacji za Ciebie, umieszczając Twoją instrukcję w sp_executesql, gdy użyjesz CommandType.Text . Ale kiedy używasz CommandType.StoredProcedure sparametryzujesz go, oszczędzając w ten sposób bazę danych. Ta druga metoda jest szybsza.

Edytuj:

Konfiguracja

Sam wykonałem kilka testów i oto wyniki.

Utwórz tę procedurę:

create procedure dbo.Test
(
   @Text1 varchar(10) = 'Default1'
  ,@Text2 varchar(10) = 'Default2'
)
as
begin
   select @Text1 as Text1, @Text2 as Text2
end

Dodaj do niego ślad za pomocą programu SQL Server Profiler.

A następnie wywołaj go za pomocą następującego kodu:

using System;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main()
        {
            CallProcedure( CommandType.Text );
            CallProcedure( CommandType.StoredProcedure );
        }

        private static void CallProcedure(CommandType commandType)
        {
            using ( SqlConnection connection = new SqlConnection("Data Source=localhost;Initial Catalog=Test;Integrated Security=SSPI;") )
            {
                connection.Open();
                using ( SqlCommand textCommand = new SqlCommand("dbo.Test", connection) )
                {
                    textCommand.CommandType = commandType;
                    textCommand.Parameters.AddWithValue("@Text1", "Text1");
                    textCommand.Parameters.AddWithValue("@Text2", "Text2");
                    using ( IDataReader reader = textCommand.ExecuteReader() )
                    {
                        while ( reader.Read() )
                        {
                            Console.WriteLine(reader["Text1"] + " " + reader["Text2"]);
                        }
                    }
                }
            }
        }
    }
}

Wyniki

W obu przypadkach połączenia są wykonywane przy użyciu RPC.

Oto, co ujawnia ślad za pomocą CommandType.Text :

exec sp_executesql N'dbo.Test',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'

A oto wynik przy użyciu CommandType.StoredProcedure :

exec dbo.Test @Text1=N'Text1',@Text2=N'Text2'

Jak widać, wywołanie tekstowe jest opakowane w wywołanie sp_executesql aby był odpowiednio sparametryzowany. Spowoduje to oczywiście niewielkie obciążenie, a tym samym moje poprzednie stwierdzenie, że użycie CommandType.StoredProcedure jest szybszy, nadal stoi.

Inną wartą uwagi rzeczą, która jest tutaj rodzajem łamania transakcji, jest to, że kiedy stworzyłem procedurę bez wartości domyślnych, otrzymałem następujący błąd:

Msg 201, Level 16, State 4, Procedure Test, Line 0 Procedura lub funkcja „Test” oczekuje parametru „@Text1”, którego nie podano.

Powodem tego jest to, jak wywołanie sp_executesql jest tworzony, jak widać parametry są zadeklarowane i zainicjowane, ale nie są używane . Aby wywołanie zadziałało, powinno wyglądać tak:

exec sp_executesql N'dbo.Test @Text1, @Text2',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'

To znaczy, gdy używasz CommandType.Text musisz dodać parametry do CommandText chyba że zawsze chcesz, aby były używane wartości domyślne.

A więc, aby odpowiedzieć na twoje pytanie

  1. Korzystanie z CommandType.StoredProcedure jest szybszy.
  2. Jeśli używasz CommandType.Text , będziesz musiał dodać nazwy parametrów do wywołania procedury, chyba że chcesz użyć wartości domyślnych.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Warunkowa wydajność agregacji

  2. Kopia zapasowa na poziomie tabeli

  3. Techniki optymalizacji zapytań w SQL Server:5 najlepszych praktyk zwiększania wydajności zapytań

  4. Paginacja w SQL Server za pomocą OFFSET/FETCH

  5. SQL Server Express a ekspresowa baza danych lokalnych