ایندکس در SQL Server و تأثیر آن بر بهینهسازی کوئریها SQL Server افزایش سرعت SQL Server نوشته شده توسط: مهدی شیشه بری تاریخ انتشار: ۲۸ مرداد ۱۳۹۶ آخرین بروزرسانی: 13 اسفند 1403 زمان مطالعه: 9 دقیقه ۴.۷ (۱۲) ایندکس در SQL Server، شاید خواندن چنین جملهای برایتان عجیب باشد؛ ” بسیاری از توسعهدهندگان نرمافزارهای کاربردی و یا مدیران دیتابیسها اهمیتی چندانی به مقوله ایندکسها نمیدهند! ” برخی از آنها صرفا ایجاد محدودیتهای Primary Key و Unique Key را برای جداول کافی میدانند و برخی دیگر حتی نسبت به چنین موضوعی آگاهی نداشته و تنها از روی عادت همیشگی، چنین محدودیتهایی را اِعمال میکنند. بعید میدانم مخاطب این مجموعه مقالات، چنین افرادی باشند. گروه دیگری هم هستند که نسبت به موضوع ایندکسگذاری و نقش آن در افزایش عملکرد کوئریها بسیار حساس هستند اما آیا واقعا به اعتبار ایجاد ایندکسهای مناسب بر روی جداول، میتوان ادعا داشت که بر تمامی مشکلات غلبه شده و بهنهایت کارآیی در دیتابیس رسیدهایم؟ شما در این مجموعه مقالات درخواهید یافت که ایندکسگذاری مناسب فقط بخشی از مسیر بهینهسازی و افزایش کارآیی است چرا که غفلت از درست نویسی کوئری و عدم رعایت استاندارها میتواند موجب تاثیر منفی عملکرد ایندکسها شود. نکته مهم: تمامی کوئریهای این مجموعه مقالات، بر روی دیتابیس AdventureWorks2016 و در محیط نرم افزار SSMS 2016 و ۲۰۱۷ اجرا شده است. عملگر LIKE همان طور که میدانید با استفاده از عملگر LIKE میتوان بر روی مقادیر فیلدهای موجود در جداول، عملیات جستجو را بر اساس کاراکترها و یا الگوهای موردنظر انجام داد. فرض کنید از جدول Address به دنبال اطلاعات مشتریانی هستیم که یکی از نشانیهای آنها که در فیلد AddressLine1 ذخیره شده است، با کاراکتر a آغاز شده باشد. در این حالت عملگر LIKE نهایت استفاده را از ایندکسهای احتمالیِ موجود بر روی این فیلد خواهد برد. USE AdventureWorks2016 GO SET STATISTICS IO ON; SELECT AddressID, AddressLine1, AddressLine2, City, StateProvinceID, PostalCode FROM Person.Address WHERE AddressLine1 LIKE 'a%'; ایندکس در SQL Server شما با اجرای کوئری بالا و مراجعه به آمار و اطلاعات I/O از بخش Messages خواهید دید. که کمترین تعداد Page برای بازیابی چنین رکوردهایی مورد بررسی قرار گرفته شده است. همچنین با مشاهده Plan اجرایی آن نیز خواهید دید که از عملیات Index Seek استفاده شده است. در این مثال عملگر LIKE بهخوبی از قابلیتهای ایندکسها استفاده کرده است. اما چالش اساسی از زمانی آغاز خواهد شد که به دنبال مقادیری باشیم که کاراکترها یا الگوی مورد ارزیابی بهعنوان بخشی از مقادیر فیلدها باشد؛ بهعبارت دیگر آنها در ابتدای مقادیر فیلدها قرار نگرفته باشند. در این حالت دیگر مزیت مرتبسازی توسط ایندکسها چندان اهمیتی نخواهد داشت و Engine مربوط به SQL Server نمیتواند از این قابلیت استفاده کند چرا که در اینجا مرتبسازی بر اساس چپترین کاراکترِ مقادیر موجود در فیلدها انجام شده است. (توجه داشته باشید که در اینجا نوعدادهی فیلد موردنظر برابر با VARCHAR میباشد.) به عنوان مثال در کوئری زیر بهدنبال رکوردهایی هستیم که مقدار فیلد AddressLine1 آن حاوی عبارت Longbrook باشد. SELECT AddressID, AddressLine1, AddressLine2, City, StateProvinceID, PostalCode FROM Person.Address WHERE AddressLine1 LIKE '%Longbrook%'; پس از اجرای کوئری بالا و با مراجعه به آمار و اطلاعات I/O از بخش Messages خواهید دید که برای بازیابی چنین رکوردهایی تعداد Page های خوانده شده نسبت به حالت قبل بهشدت افزایش پیدا کرده است. همچنین با مشاهده Plan اجرایی آن نیز خواهید دید که دیگر خبری از عملیات Index Seek نیست و SQL Server برای بازیابی رکوردها مجبور شده است تا رکوردهای جدول را Scan کند. توجه داشته باشید که این دو مثال بر روی جدولی اجرا شده که شامل بیست هزار رکورد است. در این حالت اختلاف میان عملیاتهای Index Seek و Index Scan چندان محسوس نخواهد بود اما در دیتابیسهای بزرگ و با تعداد کاربران زیاد، نوشتن چنین کوئریهایی میتواند زمینههای بروز Locking و Blocking را فراهم کند. حال میخواهم راهکارهای مختلف برای رفع چنین مشکلی را برایتان تشریح کنم. مشاهده کاملترین و بروزترین آموزش sql server در نیک آموز راهحل اول در سازمان یا شرکتمان یک قانون سفت و سخت وضع کنیم که هیچکس حق ندارد به این شکل از عملگر LIKE استفاده کند وگرنه جریمه خواهد شد! بهنظر من، این قانون بیشتر از طرف مدیران کمتجربه یا کمدانش ارائه خواهد شد؛ پس اصلا منصفانه نیست. راهحل دوم بهجای اِعمال رفتارهای غیرمدیریتی بهتر است یادی کنیم از مرحوم سهراب سپهری: ” چشم ها را باید شست، جور دیگر باید دید! “ برای رفع چنین مشکلی میتوان از FULLTEXT INDEX ها استفاده کرد هر چند که بسیاری از افراد بهدلیل عدم آشنایی، از چنین قابلیتهایی استفاده نمیکنند. با استفاده از FULLTEXT INDEX کلمات، درون یک یا چند فیلد بههمراه موقعیتشان در جدول، فهرستبندی میشوند که همین موضوع در هنگام اجرای کوئری موجب افزایش سرعت شده و دیگر نیازی به پیمایش تمامی رکوردها نخواهد بود. برای این کار میبایست ابتدا یک FULLTEXT CATALOG تعریف کنیم: CREATE FULLTEXT CATALOG IndexKiller AS DEFAULT; سپس FULLTEXT INDEX ای را بر روی فیلد موردنظر تعریف میکنیم: CREATE FULLTEXT INDEX ON Person.Address(AddressLine1) KEY INDEX PK_Address_AddressID; GO در نهایت تغییراتی کوچکی را بر روی کوئری انجام میدهیم. در اینجا میبایست در بخش WHERE یکی از توابع مربوط به FULLTEXT INDEX را با عنوان CONTAINS مورد استفاده قرار دهیم. SELECT AddressID, AddressLine1, AddressLine2, City, StateProvinceID, PostalCode FROM Person.Address WHERE CONTAINS (AddressLine1,'Longbrook'); پس از اجرای کوئری و مشاهده آمار و اطلاعات I/O خواهید دید که خوانش تعداد Page ها به مقدار قابل توجهی کاهش یافته است. همچنین با مراجعه به Plan اجرایی کوئری بالا میبینید که از عملیات Index Seek استفاده شده است. مجددا این بار هر دو کوئری را با هم اجرا میکنیم. کوئری اول با استفاده از عملگر LIKE و کوئری دوم با استفاده از قابلیت FULLTEXT Index عملیات جستجو را انجام خواهند داد. افراد علاقهمند میتوانند با مطالعه مقاله پرکاربردترین دستورات SQL Server، دانش خود را در زمینه کوئرینویسی گسترش دهند. -- Query with LIKE operator SELECT AddressID, AddressLine1, AddressLine2, City, StateProvinceID, PostalCode FROM Person.Address WHERE AddressLine1 LIKE '%Longbrook%'; -- Query with LIKE operator SELECT AddressID, AddressLine1, AddressLine2, City, StateProvinceID, PostalCode FROM Person.Address WHERE CONTAINS (AddressLine1,'Longbrook'); در تصویر زیر مقایسه آمار و اطلاعات I/O و میزان Cost مربوط به Plan اجرایی هر دو کوئری نمایش داده شده است و شما میبینید که چگونه با استفاده از قابلیت FULLTEXT INDEX زمینههای افزایش عملکرد اجرایی کوئری و کاهش استفاده از منابع را فراهم کردهایم. در قسمت قبلی ایندکس در SQL Server دیدید که چگونه با استفادهی نامناسب از عملگر LIKE در بخش WHERE، زمینههای عدم استفاده از تاثیر مثبت ایندکسها در افزایش کارآیی عملکرد کوئریها فراهم میشود. در این قسمت میخواهم شما را با یکی دیگر از سناریوهایی که موجب خنثی شدن قابلیت ایندکسها میشود، آشنا کنم. عملیات Concatenation در بسیاری از موارد شاید برایتان پیش آمده باشد که بخواهید در بخش WHERE از کوئریتان مقادیر مختلفی را با یکدیگر پیوند داده و جستجو را بر اساس آنها انجام دهید؛ در حقیقت با این کار شما میخواهید از عملیات Concatenation استفاده کنید. فرض کنید در جدول Person از دیتابیس AdventureWorks2016 میخواهید عملیات جستجو برای فردی با مشخصات Gustavo Achong را انجام دهید. برای نوشتن چنین کوئریای میبایست در بخش WHERE، فیلدهای FirstName و LastName را بههمراه یک کاراکتر فضای خالی با یکدیگر پیوند داد USE AdventureWorks2016 GO SET STATISTICS IO ON; SELECT BusinessEntityID, FirstName, LastName FROM Person.Person WHERE FirstName + ' ' + LastName = 'Gustavo Achong'; اگر به Plan اجرایی این کوئری نگاهی بیاندازید متوجه میشوید که عملیات Index Seek انجام نشده است و برای واکشی همین یک رکورد، تمامی رکوردهای جدول Person خوانده شده است! یک برنامهنویس یا مدیر دیتابیس که با قابلیتهای ایندکسها آشنا است، در اینجا تصمیم خواهد گرفت تا بر روی این دو فیلد، ایندکس مناسبی را تهیه کند. کوئری زیر این کار را انجام داده و یک NONCLUSTERED INDEX را برای این دو فیلد ایجاد خواهد کرد. CREATE INDEX IX_PersonContact_FirstNameLastName ON Person.Person (FirstName, LastName) GO [/sql] مجددا کوئری زیر را اجرا میکنیم. [sql] SELECT BusinessEntityID, FirstName, LastName FROM Person.Person WHERE FirstName + ' ' + LastName = 'Gustavo Achong'; انتظارمان این بود که پس از اجرای کوئری، ایندکس تعریفشده بر روی این دو فیلد موجب افزایش کارآیی عملکرد کوئری شود اما با نگاهی به آمار و اطلاعات I/O از بخش Messages و Plan اجرایی کوئری متوجه خواهیم شد که چنین امری تحقق نیافته است! شاید با کمی تامل در کوئری بالا به این نتیجه برسیم که با حذف کاراکتر فضای خالی از پیوند میان فیلدهای FirstName و LastName مشکل برطرف خواهد شد؛ پس کوئری را به شکل زیر اصلاح میکنیم. افراد علاقهمند میتوانند با مطالعه مقاله پرکاربردترین دستورات SQL Server، دانش خود را در زمینه کوئرینویسی گسترش دهند. SELECT BusinessEntityID, FirstName, LastName FROM Person.Person WHERE FirstName + LastName = 'GustavoAchong'; علیرغم انتظارمان باز هم تعداد Page های خوانده شده برابر با ۹۹ خواهد بود و در Plan اجرایی کوئری نیز خبری از عملیات Index Seek نیست؛ بهعبارت دیگر عملکرد این دو کوئری با یکدیگر یکسان خواهد بود. اگر فکر میکنید راهکار مناسب، استفاده از تابع CONCAT است باید به شما بگویم که سخت در اشتباه هستید. اگر دو کوئری زیر را با یکدیگر اجرا کنید خواهید دید که به لحاظ تعداد Page های خواندهشده، وضعیت مشابهی دارند اما Plan اجرایی کوئریای که در آن از تابع CONCAT استفاده شده است دارای Cost بالاتری است! این معضل در قسمت بعدی این مجموعه مقالات مورد بررسی قرار خواهد گرفت. SELECT BusinessEntityID, FirstName, LastName FROM Person.Person WHERE FirstName + LastName = 'GustavoAchong'; SELECT BusinessEntityID, FirstName, LastName FROM Person.Person WHERE CONCAT(FirstName , LastName) = 'GustavoAchong'. به نظر میرسد که باید در اینجا از عملیات پیوندِ میان فیلدها صرفنظر کرده و بهدنبال راهکار مناسبی باشیم تا از قابلیتهای ایندکسِ موجود بر روی این دو فیلد نهایت استفاده را برده باشیم. در کوئری زیر بهجای استفاده از عملگرهای + و یا تابع CONCAT از عملگر منطقی AND استفاده خواهیم کرد. یشنهاد میکنیم برای درک بهتر مفاهیم کوئری نویسی را مطالعه کنید. SELECT SELECT BusinessEntityID, FirstName,LastName FROM Person.Person WHERE FirstName + LastName = 'GustavoAchong'; SELECT BusinessEntityID, FirstName,LastName FROM Person.Person WHERE FirstName = 'Gustavo' AND LastName = 'Achong'; پس از اجرای کوئری خواهید دید که نوشتن درستِ یک کوئری چگونه زمینههای افزایش کارآیی و استفادهی بهینه از قابلیتهای ایندکسها را فراهم خواهد کرد. اجرای همزمان دو کوئری زیر و مقایسه نتایج آمار و اطلاعات I/O و Cost هر یک از آنها نیز خالی از لطف نیست. SELECT BusinessEntityID, FirstName, LastNameFROM Person.Person WHERE FirstName + LastName = 'GustavoAchong'; SELECT BusinessEntityID, FirstName, LastNameFROM Person.Person WHERE FirstName = 'Gustavo' AND LastName = 'Achong'; > در قسمتهای قبلی ایندکس در SQL Server دیدید، که چگونه با استفادهی نامناسب از عملگر LIKE و عملیات Concatenation، زمینههای عدم استفاده از تاثیر مثبت ایندکسها در افزایش کارآیی عملکرد کوئریها فراهم میشود. در قسمت سوم این مقاله میخواهم شما را با یکی دیگر از سناریوهایی که موجب خنثی شدن قابلیت ایندکسها میشود، آشنا کنم. ستونهای محاسباتی (Computed Columns) همانطور که میدانید در برخی از موارد مقادیر یک یا چندین ستون از جدولی بهصورت عبارت یا Expression تعریف میشوند. چنین مقادیری ممکن است، در حین اجرای یک کوئری و برای جلوگیری از محاسباتِ زمانِ اجرا مورد استفاده قرار گیرند. از طرفی چنین ستونهایی میتوانند با ستونهای دیگری وابستگی داشته باشند تا بهمحض هرگونه تغییری در سایر ستونها، تغییرات بر روی آنها نیز اِعمال شود. به چنین ستونهایی Computed Columns گفته میشود. زمانی که شما مجبور هستید تا نتیجه اجرای یک تابع یا محاسبات مبتنی بر چندین ستون را در جدولتان نگهداری کنید، استفاده از ستونهای محاسباتی میتواند برای شما مفید واقع شود. همواره به این نکته مهم توجه داشته باشید، که قابلیت استفاده از ایندکسهای موجود بر روی ستونهایی که بر اساس آنها ستونهای محاسباتی شکل گرفته است. امکان پذیر نخواهد بود! برای بررسی این موضوع، ابتدا دو ستون محاسباتی جدید را برای جدول Person درنظر میگیریم. اولین ستون محاسباتی شامل ترکیبی از فیلدهای نام و نامخانوادگی است اما دومین ستون محاسباتی معنای خاصی نداشته و صرفا جهت بررسی یک سناریو تعریف میشود. افراد علاقهمند میتوانند با مطالعه مقاله پرکاربردترین دستورات SQL Server، دانش خود را در زمینه کوئرینویسی گسترش دهند. USE AdventureWorks2016 GO ALTER TABLE Person.Person ADD FirstLastName AS (FirstName + ' ' + LastName) ,CalculateValue AS (BusinessEntityID * EmailPromotion); اکنون کوئریهای زیر را اجرا میکنیم. SET STATISTICS IO ON SELECT BusinessEntityID, FirstName, LastName, FirstLastName FROM Person.Person WHERE FirstLastName = 'Gustavo Achong'; SELECT BusinessEntityID, CalculateValue FROM Person.Person WHERE CalculateValue = 198; با مراجعه به Plan اجرایی این کوئریها خواهیم دید، که جهت بازیابی رکوردها از عملیات Scan استفاده شده است. در قسمتهای قبلی این مجموعه مقالات به شما تذکر دادیم که این عملیات با افزایش حجم دیتابیس، رکوردهای جدول و تعداد کاربران همزمان میتواند احتمال بروز پدیده Blocking و استفاده از I/O های بیشتر برای درخواستها را فراهم کند. این موضوع در بخش آمار و اطلاعات I/O نیز قابل مشاهده است که چگونه برای بازیابی نتایج موردنظر، تمامی رکوردها مورد ارزیابی قرار گرفته شده است. با توجه به عدم استفاده از ایندکس ستونهای مبداء در ستونهای محاسباتی، اکنون برای این دو ستونِ جدید ایندکسهایی از نوع NONCLUSTERED تعریف میکنیم. CREATE INDEX IX_PersonPerson_FirstLastName ON Person.Person(FirstLastName); CREATE INDEX IX_PersonPerson_CalculateValue ON Person.Person(CalculateValue); با اجرای مجدد کوئریها خواهیم دید که بازیابی رکوردها از طریق عملیات Index Seek انجام شده است. مقایسه آمار و اطلاعات I/O نیز نشان از کاهش چشمگیر تعداد Page های خواندهشده در این عملیات خواهد داشت. در قسمتهای قبلی ایندکس در SQL Server دیدید که چگونه با نوشتن یک کوئری نامناسب در هنگام جستجوی مقادیر مختلف از جداول، ناخواسته زمینههای لازم برای عدم استفاده از ایندکسهای موجود را فراهیم میکنیم! توابع تک مقدار یا اسکالر (Scalar Functions) در این قسمت میخواهیم درخصوص عوارض استفاده از توابع تکمقدار یا Scalar Functionها در هنگام نوشتن کوئریها و در بخش WHERE با شما صحبت کنیم! همانطور که میدانید مایکروسافت توابع مختلفی را بهشکل Built-in در SQL Server ارائه کرده است. این توابع در قالب دستهبندیهای مختلفی، قابلیت کار با انواعداده از قبیل رشتهها، اعداد، تاریخ، زمان و … را فراهم میکنند. ما میتوانیم با استفاده از اینگونه توابع علاوهبر صرفهجویی در زمان، به افزایش کارآیی کوئریها نیز کمک شایانی کرده باشیم. عملکرد این توابع بهگونهای است که با تغییر در شکل اصلی مقادیر فیلدها، مقادیر مناسبتری را برای نوشتن کوئریهایِ مختلف فراهم خواهد کرد. این کار حتی از طریق توابعی که توسط کاربران و با عنوان User Define Function شناخته میشود نیز امکانپذیر است اما باید توجه داشت که چنین تغییراتی میتواند موجب خنثی شدن عملکرد ایندکسهای موجود بر روی مقادیر فیلدهای جداول شود چرا که استفاده از اینگونه توابع، شکل اصلی مقادیر فیلدها را دستخوش تغییر میکند. بدیهی است که این مقادیر، هیچگونه سنخیتی با مقادیر ایندکسگذاری شده در حین عملیات ایندکسگذاری ندارند. بهعبارت سادهتر هیچگونه آماری از میزان فراوانی آنها در دسترس نبوده تا بر اساس آنها بهینهسازِ SQL Server (Query Optimizer) اقدام به ایجاد یک Plan بهینه از آنها داشته باشد. برای آنکه تاثیر اینگونه از توابع را بر روی روند اجرایی کوئریها ببینید به اسکریپتهای زیر توجه کنید: USE AdventureWorks2014 GO SET STATISTICS IO ON -- Query 1 SELECT BusinessEntityID, FirstName, LastName FROM Person.Person WHERE FirstName = 'Gustavo'; GO -- Query 2 SELECT BusinessEntityID, FirstName, LastName FROM Person.Person WHERE RTRIM(FirstName) = 'Gustavo'; GO هر دو کوئری بالا قرار است اطلاعات مربوط به رکوردی را نمایش دهند که مقدار فیلد FirstName آن برابر با Gustavo است. پس از اجرای همزمان هر دو کوئری و با مراجعه به آمار و اطلاعات I/O خواهید دید، کوئری دوم که در بخش WHERE از تابع RTRIM استفاده کرده است، نسبت به کوئری اول تعداد Page بیشتری را خوانده است! این اختلاف بسیار فاحش، در مقایسهی Plan اجرایی و میزان استفاده از منابع نیز بهوضوح قابل مشاهده است. واقعیت این است که برای رفع این معضل نمیتوان یک راهکار عمومی ارائه کرد. شاید توجه به این جمله کلیدی، چندان دور از واقعیت نباشد: “پیشگیری بهتر از درمان است!” افراد علاقهمند میتوانند با مطالعه مقاله پرکاربردترین دستورات SQL Server، دانش خود را در زمینه کوئرینویسی گسترش دهند. ارائه یک راهحل مناسب، کاملا متناسب با پارامترهایی همچون مدل کسبوکار و قواعد حاکم بر آن، مدل طراحی دیتابیس، ساختار رکوردهای موجود در جداول و … است. به عنوان مثال فرض کنید قرار است تمامی سفارشاتِ مرتبط با سال ۲۰۱۲ و ماه ۱۲ را از جدول SalesOrderHeader در خروجی نمایش دهیم. برای انجام این کار میتوان به دو روش اقدام کرد. به اسکریپتهای زیر توجه کنید: USE AdventureWorks2014 GO CREATE INDEX IX_SalesSalesOrderHeader_OrderDate ON Sales.SalesOrderHeader(OrderDate); GO SET STATISTICS IO ON; -- Query 1 SELECT SalesOrderID, OrderDate FROM Sales.SalesOrderHeader WHERE MONTH(OrderDate) = 12 AND YEAR(OrderDate) = 2012; GO -- Query 2 SELECT SalesOrderID, OrderDate FROM Sales.SalesOrderHeader WHERE OrderDate BETWEEN '20121201' AND '20121231'; GO از آنجا که بر روی فیلد OrderDate ایندکسی مناسبی وجود ندارد، ابتدا بر روی آن ایندکسی از نوع Non-Clustered ایجاد میکنیم. در ادامه خواهید دید که در اولین کوئری از توابع YEAR و MONTH برای استخراج مقادیر سال و ماه استفاده شده است اما در کوئری دوم صرفا با استفاده از عملگر BETWEEN و تعیین یک بازه زمانی، این کار انجام شده است. پس از اجرای همزمان هر دو کوئری و مراجعه به آمار و اطلاعات I/O و Plan اجرایی خواهید دید که عدم استفاده از دو تابع YEAR و MONTH تا چه حدی میتواند به افزایش عملکرد کوئری و استفاده کمتر از منابع، کمک کند. سخن پایانی ایندکس در SQL Server، بنابراین همواره این نکته را بهخاطر داشته باشید که هنگام استفاده از Scalar Function ها در بخش WHERE اگر تحت هر شرایطی مقادیر ستونها توسط توابع دستخوش تغییرات شوند آنگاه بهاحتمال بسیار زیاد، ایندکسهای موجود بر روی ستونها در هنگام اجرای کوئری، توسط بهینه ساز مورد استفاده قرار نخواهند گرفت. ما در نیک آموز منتظر نظرات ارزشمند شما درباره این مقاله هستیم. چه رتبه ای میدهید؟ میانگین ۴.۷ / ۵. از مجموع ۱۲ اولین نفر باش دانلود مقاله ایندکس در SQL Server و تأثیر آن بر بهینهسازی کوئریها فرمت PDF 7 صفحه حجم 1 مگابایت دانلود مقاله معرفی نویسنده معرفی محصول مسعود طاهری دوره ۳ در ۱ آموزش performance tuning در SQL Server 6.700.000 تومان 4.020.000 تومان مقالات مرتبط ۲۷ اسفند هوش تجاری هوش تجاری در صنعت بیمه | بهبود عملکرد و افزایش سودآوری تیم فنی نیک آموز ۲۱ اسفند زبان های برنامه نویسی شرح repository pattern در #C | معرفی جامع + نحوه ساخت تیم فنی نیک آموز ۱۵ اسفند هوش تجاری بهینهسازی عملکرد Power BI | افزایش سرعت تیم فنی نیک آموز ۱۲ اسفند زبان های برنامه نویسی تزریق وابستگی در asp.net core | بررسی اصول و بهترین روشها تیم فنی نیک آموز دیدگاه کاربران لغو پاسخ دیدگاه نام و نام خانوادگی ایمیل ذخیره نام، ایمیل و وبسایت من در مرورگر برای زمانی که دوباره دیدگاهی مینویسم. موبایل برای اطلاع از پاسخ لطفاً مرا با خبر کن ثبت دیدگاه Δ علیرام ۰۹ / ۱۱ / ۹۹ - ۰۷:۲۳ چطور میشه در دیتابیس های حجیم پیشرفت این مدل ایندکس رو دید ؟ بهردرصد منظورمه چون ایندکس fulltext بسیار زمان بره پاسخ به دیدگاه آرزو محمدزاده ۲۰ / ۰۵ / ۰۰ - ۰۹:۰۴ با سلام و وقت بخیر شما می توانید با استفاده از این DM View سیستمی و فیلد percent_complete در صد پیشرفت رو بررسی کنید. sys.dm_exec_requests برای استفاده از این DM View به لینک زیر مراجعه کنید https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-exec-requests-transact-sql?view=sql-server-ver15 پاسخ به دیدگاه Helia ۲۶ / ۱۲ / ۹۷ - ۰۱:۵۲ عالی بود استاد، ممنون پاسخ به دیدگاه امین ثریا ۰۲ / ۰۷ / ۹۶ - ۰۴:۲۲ عالی بود پاسخ به دیدگاه ha_zarabi_vb6@outlook.com ۰۷ / ۰۶ / ۹۶ - ۰۵:۱۲ با سلام و خسته نباشید خدمت جناب آقای مهندس مهدی شیشه بری از بابت این مقاله بسیار مفید و عالی بسیار ممنونم این مقاله مقاله ای هست که برای هر کسی که می خواهد sql server را حتی به صورت خیلی متوسط هم یاد بگیر خیلی مفید هست چون خیلی به درد بخور هست از شما ممنونم با تشکر از شما پاسخ به دیدگاه ha_zarabi_vb6@outlook.com ۰۷ / ۰۶ / ۹۶ - ۰۵:۱۲ با سلام و خسته نباشید خدمت جناب آقای مهندس مهدی شیشه بری از بابت این مقاله بسیار مفید و عالی بسیار ممنونم این مقاله مقاله ای هست که برای هر کسی که می خواهد sql server را حتی به صورت خیلی متوسط هم یاد بگیر خیلی مفید هست چون خیلی به درد بخور هست از شما ممنونم با تشکر از شما پاسخ به دیدگاه osi56k ۰۷ / ۰۶ / ۹۶ - ۱۱:۱۲ خیلی ممنون. یک پیشنهاد دارم. زیر هر مقاله یک دکمه تشکر باشه که برای همین به کار بره و فضای کامنت برای تشکر پر نکنیم. پاسخ به دیدگاه Mehdi ۰۷ / ۰۶ / ۹۶ - ۱۰:۵۸ بسیار کاربردی، سپاس از شما. پاسخ به دیدگاه مهدی شیشه بری ۰۷ / ۰۶ / ۹۶ - ۰۹:۳۰ خوانش این یکی مقاله را هم از دست ندهید: https://goo.gl/iznSVu پاسخ به دیدگاه مهدی شیشه بری ۰۷ / ۰۶ / ۹۶ - ۰۹:۳۰ خوانش این یکی مقاله را هم از دست ندهید: https://goo.gl/iznSVu پاسخ به دیدگاه قاسمی ۰۷ / ۰۶ / ۹۶ - ۰۵:۲۸ عالی بود. فقط فکز میکنم تصویر دوم (مربوط به کوئری LIKE ‘%Longbrook%’;) اشتباه گذاشته شده، و عکس مربوط به کوئری فول-تکست هم همان است. (آدرس هر دو https://nikamooz.com/wp-content/uploads/2017/08/kill_index_3-e1503163450575.jpg است) پاسخ به دیدگاه 1 2