تقویت عملکرد Dapper
بسیاری از اوقات ما شروع به نوشتن کد می کنیم و جزئیاتی را که می تواند بر عملکرد سیستم ما تأثیر بگذارد نادیده می گیریم. ما معتقدیم که مشکل عملکرد بزرگتر از آنچه هست است و در نتیجه مسیرهای پیچیده تری را دنبال می کنیم.
بیایید یک چیز ساده را در نظر بگیریم. شما از Dapper استفاده می کنید، یک Micro ORM، که به دلیل سرعت خود در مقایسه با سایر ORM ها شناخته شده است. اما آیا از Dapper به درستی استفاده می کنید و از این عملکرد نهایت استفاده را می برید؟
آیا تمایل دارید پارامترهایی را که به پرس و جوهای خود ارسال می کنید با دقت شناسایی کنید؟
بیایید یک کلاس مشتری و یک جدول برای ذخیره مشتریان ایجاد کنیم:
class Cliente
{
public string Nome { get; set; }
public int Id { get; set; }
public string CPF { get; set; }
}
CREATE TABLE CLIENTE (
ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
NOME VARCHAR(200) NOT NULL,
CPF CHAR(11) NOT NULL
)
پس از ایجاد جدول، 1000 CPF (جعلی) را در یک حلقه قرار می دهیم و یک شاخص برای CPF ایجاد می کنیم:
CREATE UNIQUE NONCLUSTERED INDEX IX_CLIENTE_CPF
ON Cliente (Cpf)
INCLUDE (Nome)
حالا بیایید یک کد ساده بنویسیم تا مشتری را از طریق CPF دریافت کنیم، که یک کد رایج در بسیاری از برنامهها است:
IConfigurationBuilder builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", false, true);
IConfigurationRoot config = builder.Build();
SqlConnection sqlConnection =
new SqlConnection(
config.GetConnectionString("ecommerceConnectionString")
);
sqlConnection.Open();
var cliente = sqlConnection.QueryFirstOrDefault<Cliente>(
"select * from Cliente where CPF = @cpf",
new { cpf = "00000000090" });
sqlConnection.Close();
آنچه ما امیدواریم این است که پرس و جو اجرا شده در پایگاه داده تا حد امکان کارآمد باشد زیرا ما یک نمایه توسط ستون CPF داریم. بیایید ثابت کنیم که شاخص وجود دارد و ما بهترین برنامه اجرایی ممکن را داریم.
این پرس و جو با انجام جستجوی فهرست بر روی شاخص CPF که قبلا ایجاد کردیم، اجرا شد.
حالا بیایید کوئری «همان» را از برنامه اجرا کنیم.
اجرای پرس و جو به طور مستقیم در SQL و دریافت برنامه اجرا.
نتیجه آن چیزی که انتظار می رفت نبود. به جای اجرای Index Seek، پرس و جو ایجاد شده توسط Dapper یک Index Scan انجام داد. این اتفاق به این دلیل رخ داد که Dapper پارامتر query را به طور پیشفرض به صورت NVARCHAR تفسیر کرد که باعث شد SQL Server پارامتر را تبدیل کند و طرح اجرا را تغییر دهد و بر عملکرد پرس و جو تأثیر بگذارد.
برای جلوگیری از این مشکل و بهبود عملکرد پرس و جو، لازم است نوع پارامتر رشته را به درستی اطلاع دهید. در Dapper می توانیم از کلاس DbString برای تعیین نوع پارامتر استفاده کنیم.
var cliente = sqlConnection.QueryFirstOrDefault<Cliente>(
"select * from Cliente where CPF = @cpf",
new
{
cpf = new DbString
{
IsAnsi = true,
IsFixedLength = true,
Length = 11,
Value = "00000000090"
}
});
با تنظیم ویژگی های DbString، Dapper یک پرس و جو با نوع پارامتر درست ایجاد می کند و به SQL Server اجازه می دهد تا Index Seek را انجام دهد. توجه داشته باشید که تعیین صحیح ویژگی با توجه به نوع داده ستون در پایگاه داده مهم است.
DbString یک کلاس Dapper است که امکان تعیین نوع دقیق پارامتری که به پایگاه داده ارسال می شود را می دهد. بنابراین Dapper دستورالعملی را تولید می کند که از نوع داده صحیح برای پارامتر استفاده می کند. با این کار، از تبدیل های غیر ضروری جلوگیری می کنیم و به بهبود عملکرد پرس و جو کمک می کنیم.
سازنده DbString به شما اجازه می دهد تا ویژگی های مختلفی مانند IsAnsi، IsFixedLength، Length و Value را تنظیم کنید. ویژگی IsAnsi نشان می دهد که نوع داده ANSI یا Unicode است. ویژگی IsFixedLength نشان می دهد که نوع داده ثابت است یا طول متغیر. ویژگی Length حداکثر طول فیلد را نشان می دهد و خاصیت Value مقدار پارامتر است.
پارامترها بر اساس نوع:
این جزئیات کوچک اغلب در طول پیاده سازی ما مورد توجه قرار نمی گیرد و می تواند به طور قابل توجهی بر عملکرد برنامه های ما تأثیر بگذارد و به طور مستقیم بر تجربه کاربر تأثیر بگذارد. بنابراین، مهم است که برای بهینه سازی کد با استفاده از شیوه ها و ابزارهای خوب که به ما در شناسایی و اصلاح مشکلات احتمالی کمک می کند، وقت بگذاریم.
بعدی!