نگارش نهایی SQL Server 2022 منتشر شد
Today, we announced the general availability of SQL Server 2022, the most Azure-enabled release of SQL Server yet, with continued innovation across performance, security, and availability1. This marks the latest milestone in the more than 30-year history of SQL Server.
سری بررسی مقدمات Blazor
Blazor Fundamentals Tutorial
Blazor server-side vs client-side (WebAssembly) | What should you choose?
What are Razor Components? | Blazor Tutorial 1
Dependency Injection | Blazor Tutorial 2
What are Blazor Layouts? | Blazor Tutorial 3
Routing and Navigation | Blazor Tutorial 4
JS Interop: Calling JavaScript from C# | Blazor Tutorial 5
JS Interop: Calling C# methods from JavaScript | Blazor Tutorial 6
Creating Forms with Validation | Blazor Tutorial 7
How to add Authentication in Server-side Blazor | Blazor Tutorial 8
Authorization in Server-Side Blazor | Blazor Tutorial 9
How to use HTML5 Web Storage in Blazor | Blazor Tutorial 10
Managing Blazor state using Redux | Blazor Tutorial 11
Creating a desktop application using Blazor and Electron | Blazor Tutorial 12
Deploying Server-Side Blazor in Azure with SignalR service | Blazor Tutorial 13
Building cross platform mobile apps with Blazor (Experimental)
کتابخانه instafetch
If you use the Instagram API to make a call, you will only get 33 results back, no matter what you specify in the count paramter. Instafetch will help you fetch more media than the limit imposes, in exchange for more API calls, which can count against your hourly limit. Demo
npm v5.0.0 منتشر شد
بررسی مفهوم دیتاست خارجی و درونی
ابتدا در management studio از منوی Query، گزینهی Include actual execution plan را انتخاب میکنیم. سپس کوئریهای زیر را اجرا میکنیم:
USE [WideWorldImporters]; GO SET STATISTICS IO ON; GO /* What's are the inner and outer data sets? */ SELECT [ol].[OrderLineID], [o].[CustomerID] FROM [Sales].[OrderLines] [ol] INNER JOIN [Sales].[Orders] [o] ON [ol].[OrderID] = [o].[OrderID] WHERE [o].[CustomerID] = 185; GO
در اینجا دیتاست خارجی، همان index seek بالایی است که بر روی جدول Orders انجام شدهاست. اولین ردیف بازگشت داده شدهی توسط آن به همراه OrderID مربوطه را به حلقهی تو در توی Inner Join ارسال میکند. سپس index seek دوم بر روی جدول OrderLines، بر اساس OrderID دیتاست خارجی، ردیف مرتبطی را در صورت وجود یافته و به حلقهی تو در توی Inner Join بازگشت میدهد که در نهایت به select ارسال میشود و این عملیات به همین ترتیب ادامه پیدا میکند. این خلاصهی کاری است که یک حلقهی تو در تو انجام میدهد.
سؤال: اگر جای این دیتاستها را عوض کنیم چه اتفاقی رخ خواهد داد؟
در کوئری زیر توسط گزینهی FORCE ORDER سبب شدهایم تا جای دیتاستهای OUTER/INNER تغییر کند (البته این query hint، کاربرد عملی ندارد و صرفا جهت نمایش دیتاستها از آن استفاده کردهایم):
SELECT [ol].[OrderLineID], [o].[CustomerID] FROM [Sales].[OrderLines] [ol] INNER JOIN [Sales].[Orders] [o] ON [ol].[OrderID] = [o].[OrderID] WHERE [o].[CustomerID] = 185 OPTION (FORCE ORDER);
یک نکته: در این تصاویر بجای nested loop، از عملگر Hash Match استفاده شدهاست. اگر بخواهیم بهینه سازی کوئری را وادار کنیم تا از nested loop استفاده کند، میتوان کوئری فوق را توسط یک INNER LOOP JOIN به صورت زیر نوشت:
SELECT [ol].[OrderLineID], [o].[CustomerID] FROM [Sales].[OrderLines] [ol] INNER LOOP JOIN [Sales].[Orders] [o] ON [ol].[OrderID] = [o].[OrderID] WHERE [o].[CustomerID] = 185 OPTION (FORCE ORDER); GO
همانطور که مشاهده میکنید اینبار به علت بالا رفتن تعداد ردیفهایی که باید پردازش کند، به یک پلن بسیار غیر بهینه رسیدهاست که برای بهبود آن مجبور شدهاست Parallelism را نیز فعال کند.
در این حالت اگر هر سه کوئری فوق را با هم اجرا کنیم، تا بتوانیم هزینهی آنها را در کوئری پلن نهایی تولید شده، با یکدیگر مقایسه کنیم، هزینهی کوئری اول صفر درصد، کوئری دوم 1 درصد و کوئری سوم 99 درصد نسبت به کل batch محاسبه میشود. علت آن را نیز در برگهی messages، با مشاهدهی logical reads 477304 مربوط به کوئری سوم میتوان مشاهده کرد که نسبت به سایر کوئریها بسیار بیشتر است. بنابراین بهتر است در کار بهینه ساز کوئریها به صورت دستی دخالت نکنیم!
بهبود کارآیی یک کوئری، با حذف حلقهی تو در توی کوئری پلن آن در حالت Key lookup
کوئری زیر را با فرض انتخاب گزینهی Include actual execution plan در منوی کوئری، اجرا میکنیم:
SELECT [ContactPersonID], [OrderDate], [CustomerPurchaseOrderNumber] FROM [Sales].[Orders] WHERE [ContactPersonID] = 3144;
ایندکسهایی که در این کوئری پلن استفاده شدهاند، شامل موارد پیشفرض زیر هستند؛ یکی بر روی OrderID که کلید اصلی جدول است، تشکیل شده و دیگری بر روی ContactPersonID که در قسمت where کوئری فوق مورد استفاده قرار گرفتهاست:
ALTER TABLE [Sales].[Orders] ADD CONSTRAINT [PK_Sales_Orders] PRIMARY KEY CLUSTERED ( [OrderID] ASC ) GO CREATE NONCLUSTERED INDEX [FK_Sales_Orders_ContactPersonID] ON [Sales].[Orders] ( [ContactPersonID] ASC )
برای بهبود این وضعیت، NONCLUSTERED INDEX تعریف شده را به صورت زیر تغییر میدهیم تا ستونهای OrderDate و CustomerPurchaseOrderNumber را INCLUDE کند:
CREATE NONCLUSTERED INDEX [FK_Sales_Orders_ContactPersonID] ON [Sales].[Orders] ( [ContactPersonID] ASC ) INCLUDE ( [OrderDate], [CustomerPurchaseOrderNumber] ) WITH (DROP_EXISTING = ON) ON [USERDATA]; GO
SELECT [ContactPersonID], [OrderDate], [CustomerPurchaseOrderNumber] FROM [Sales].[Orders] WHERE [ContactPersonID] = 3144;
چون ایندکس جدید تعریف شده کاملا کوئری ما را پوشش میدهد، دیگر نیازی به ایجاد یک nested loop، جهت کار با چندین index متفرقه نیست.
بهبود کارآیی یک کوئری، با حذف حلقهی تو در توی کوئری پلن آن در حالت RID lookup
در اینجا یک جدول کپی را از روی جدول اصلی Orders ایجاد کردهایم؛ به همراه تعریف یک NONCLUSTERED INDEX بر روی ستون ContactPersonID آن:
USE [WideWorldImporters] GO DROP TABLE [Sales].[Copy_Orders] GO SELECT * INTO [Sales].[Copy_Orders] FROM [Sales].[Orders]; GO CREATE NONCLUSTERED INDEX [NCI_Copy_Orders_ContactPersonID] ON [Sales].[Copy_Orders] ( [ContactPersonID] ); GO
SELECT [ContactPersonID], [OrderDate], [CustomerPurchaseOrderNumber] FROM [Sales].[Copy_Orders] WHERE [ContactPersonID] = 3144;
در اینجا یک nested loop را به همراه RID lookup داریم (RID به معنای row id است). همچنین واژهی heap نیز ذکر شدهاست. در این حالت اطلاعات یک چنین جدولی بدون هیچگونه ترتیبی ذخیره شدهاند؛ بنابراین نیاز به شماره ردیف آن (RID) برای برقراری ارتباطات میباشد. Key lookup زمانی رخ میدهند که یک جدول دارای یک clustered index باشد و RID lookup، در حالت عکس آن رخ میدهد. دقیقا مانند جدول کپی ایجاد شده، که دارای یک clustered index نیست.
در صورت مشاهدهی RID lookup نیز میتوانیم ستونهایی از کوئری را که در NONCLUSTERED INDEX ذکر نشدهاند، include کنیم:
CREATE NONCLUSTERED INDEX [NCI_Copy_Orders_ContactPersonID] ON [Sales].[Copy_Orders] ( [ContactPersonID] ASC ) INCLUDE ( [OrderDate], [CustomerPurchaseOrderNumber] ) WITH (DROP_EXISTING = ON) ON [USERDATA]; GO
NET Core SDK 3.1.106. منتشر شد
See the following table to select the correct download
OS | Development Environment | .NET Core SDK |
---|---|---|
Windows | Visual Studio 2019 version 16.6 | 3.1.302 |
Windows | Visual Studio 2019 version 16.4 | 3.1.106 |
MacOS | Visual Studio for Mac | Visual Studio for Mac .NET Core Support |
وبلاگها و سایتهای ایرانی
Visual Studio
امنیت
- رمزنگاری کوانتمی و شبکهای رمزنگاری شده با این روش
ASP. Net
طراحی وب
اسکیوال سرور
به روز رسانیها
ابزارها
- نگارش جدید برنامه RSS Bandit . (برنامهای سورس باز نوشته شده با سی شارپ)
- Visual Round Trip Analyzer (استفاده از NetMon API)
سیشارپ
- Interactive GUI Shell از توسعه دهندگان تیم Mono
عمومی دات نت
- آشنایی با کلاس CommaDelimitedStringCollection در دات نت فریم ورک
- مونو و دات نت گزارشی از PDC2008
CPP
دلفی
- CompilerPlugin برای دلفی 2009. (توسط آن میتوان پروژههای دلفی 2007 را با دلفی 2009 نیز کامپایل کرد)
- نسخه جدید CnPack منتشر شد. (با پشتیبانی دلفی 5 تا 2009)
ویندوز
- آنالیز crash dumps ویندوز . (آیا میدانید صفحات آبی ویندوز را چگونه باید تفسیر کرد؟)
Office
- آشنایی با یک سری از اصطلاحات outlook 2007 برای برنامه نویسها. (اگر قصد داشته باشید یک add-in را برای outlook 2007 با استفاده از امکانات VSTO توسعه دهید، آشنایی با این اصطلاحات بسیار ضروری خواهد بود)
متفرقه