[vc_row][vc_column][vc_column_text]
مقدمه
از زمان انتشار SQL Server 2017 برای لینوکس، مایکروسافت تقریباً کل مبنا را تغییر داده است. مایکروسافت یک دنیای کاملاً جدید از امکانات را برای پایگاه داده رابطه ای فعال کرد و آنچه را که تا آن زمان فقط در فضای ویندوز در دسترس بود برای لینوکس نیز ارائه می کرد.
یک متخصص دیتابیس (DBA) خواهد گفت که نسخه لینوکس SQL Server 2019 چندین تفاوت از نظر ویژگی با نسخه ویندوز خود دارد، مانند:
- بدون SQL Server Agent
- بدون FileStream
- نداشتن رویه های ذخیره شده توسعه یافته (Store Procedure) سیستم (مانند xp_cmdshell)
با این وجود تصمیم گرفتم تا آنها را با هم مقایسه کنم؛ بنابراین، چند ماشین مجازی ساختم و چند آزمایش ساده را آماده کردم و داده هایی را جمع آوری کردم تا به شما ارائه کنم. با من همراه باشید تا این تفاوت ها را ببینیم.[/vc_column_text][vc_empty_space height=”20px”][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
ملاحظات اولیه
در این قسمت مشخصات هر (ماشین مجازی) VM آمده است:
Windows
- سیستم عامل ویندوز 10
- vCPU 4
- رم 4 گیگابایت
- 30 گیگابایت SSD
[/vc_column_text][vc_empty_space height=”20px”][vc_single_image image=”3746″ img_size=”full” alignment=”center”][vc_empty_space height=”20px”][vc_column_text]لینوکس
- سرور اوبونتو 20.04 LTS
- 4 vCPU
- رم 4 گیگابایت
- 30 گیگابایت SSD
[/vc_column_text][vc_empty_space height=”20px”][vc_single_image image=”3747″ img_size=”full” alignment=”center”][vc_empty_space height=”20px”][vc_column_text]برای نصب SQL Server، جدیدترین نسخه را برای هر دو سیستم عامل انتخاب کردم: SQL Server 2019 Developer Edition CU10[/vc_column_text][vc_empty_space height=”20px”][vc_single_image image=”3748″ img_size=”full” alignment=”center”][vc_empty_space height=”20px”][vc_column_text]در هر نصب، تنها چیزی که فعال میشد، Instant File Initialization بود (به طور پیش فرض در لینوکس فعال است، بهصورت دستی در ویندوز فعال می شود). بهغیراز آن، مقادیر پیش فرض برای بقیه تنظیمات باقی می ماند.
در ویندوز، میتوانید Instant File Initialization را از طریق Wizard نصب و فعال شود.[/vc_column_text][vc_empty_space height=”20px”][vc_single_image image=”3749″ img_size=”full” alignment=”center”][vc_empty_space height=”20px”][vc_column_text]در این پست ویژگی کار Instant File Initialization در لینوکس را توضیح نمی دهد. با این حال، شما می توانید بعداً به مقالات مرتبط مراجعه کنید (توجه داشته باشید که از نظر فنی کمی سنگین می باشد).
تست شامل چه مواردی است؟
1. در هر SQL Server 2019، من یک پایگاه داده آزمایشی را نصب کردم و یک جدول با تنها یک فیلد (NVARCHAR(MAX)) ایجاد کردم.
2. با استفاده از یک رشته تولید شده به صورت تصادفی از 1000000 کاراکتر، مراحل زیر را انجام دادم:
- *تعداد X ردیف را در جدول تست وارد کنید.
- مدت زمان تکمیل عبارت INSERT را اندازه بگیرید.
- اندازه فایل های MDF و LDF را اندازه گیری کنید.
- تمام سطرهای جدول تست را حذف کنید.
- ** اندازه گیری زمان لازم برای تکمیل عبارت DELETE.
- اندازه فایل LDF را اندازه گیری کنید.
- پایگاه داده تست را حذف کنید.
- دوباره پایگاه داده تست را ایجاد کنید.
- همان چرخه را تکرار کنید.
- X برای 1000، 5000، 10000، 25000 و 50000 ردیف اجرا شد.
**من می دانم که یک دستور TRUNCATE کار را با کارایی بیشتری انجام می دهد، اما هدف من در اینجا این است که ثابت کنم هر
گزارش تراکنش چقدر برای عملیات حذف در هر سیستم عامل محاسبه می شود.
در اینجا بخش هایی از کد TSQL است که برای آزمایش ها در هر سیستم عامل استفاده شده است:[/vc_column_text][vc_empty_space height=”20px”][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
کدهای لینوکس TSQL
ایجاد پایگاهداده و جداول
DROP DATABASE IF EXISTS test CREATE DATABASE test ON (FILENAME= '/var/opt/mssql/data/test.mdf', NAME = test, FILEGROWTH = 128MB) LOG ON (FILENAME= '/var/opt/mssql/data/test_log.ldf',NAME = test_log, FILEGROWTH = 64MB); CREATE TABLE test.dbo.ubuntu (long_string NVARCHAR(MAX) NOT NULL )
اندازه فایل های MDF و LDF برای پایگاه داده تست
SELECT DB_NAME(database_id) AS 'DB', type_desc AS 'Type', state_desc AS 'State', CONVERT(DECIMAL(10,2), size*8/1024) AS 'Size', CONVERT(DECIMAL(10,2), growth*8/1024) AS 'Growth' FROM sys.master_files WHERE DB_NAME(database_id) = 'test'
اسکرین شات زیر اندازه فایل های داده را زمانی که چیزی در پایگاه داده ذخیره نشده است را نشان می دهد:
[/vc_column_text][vc_empty_space height=”20px”][vc_single_image image=”3750″ img_size=”full” alignment=”center”][vc_empty_space height=”20px”][vc_column_text]
SELECT servicename, instant_file_initialization_enabled FROM sys.dm_server_services WHERE servicename = 'SQL Server (MSSQLSERVER)'
[/vc_column_text][vc_empty_space height=”20px”][vc_single_image image=”3751″ img_size=”full” alignment=”center”][vc_empty_space height=”20px”][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]کدهای TSQL ویندوز
ایجاد پایگاهداده و جداول
DROP DATABASE IF EXISTS test CREATE DATABASE test ON (FILENAME='S:\ProgramFiles\MicrosoftSQLServer\MSSQL15.WINDOWS\MSSQL\DATA\test.mdf', NAME = test, FILEGROWTH = 128MB) LOG ON (FILENAME=''S:\ProgramFiles\MicrosoftSQLServer\MSSQL15.WINDOWS\MSSQL\DATA\test_log.ldf',NAME = test_log, FILEGROWTH = 64MB); CREATE TABLE test.dbo.windows( long_string NVARCHAR(MAX) NOT NULL )
اندازه فایل های MDF و LDF برای پایگاه داده تست
SELECT DB_NAME(database_id) AS 'DB', type_desc AS 'Type', state_desc AS 'State', CONVERT(DECIMAL(10,2),size*8/1024) AS 'Size', CONVERT(DECIMAL(10,2),growth*8/1024) AS 'Growth' FROM sys.master_files WHERE DB_NAME(database_id) = 'test'
اسکرین شات زیر اندازه فایل های داده را زمانی که چیزی در پایگاه داده ذخیره نشده است نشان می دهد:
[/vc_column_text][vc_empty_space height=”20px”][vc_single_image image=”3752″ img_size=”full” alignment=”center”][vc_empty_space height=”20px”][vc_column_text]در زیر پرس و جوهایی است برای تعیین اینکه آیا Instant File Initialization فعال است یا خیر:
SELECT servicename, instant_file_initialization_enabled FROM sys.dm_server_service WHERE servicename = 'SQL Server (MSSQLSERVER)'
اسکریپت برای اجرای دستور INSERT:
limit@،در این قسمت تعداد سطرهایی را برای درج در جدول تست مشخص کردم.
برای لینوکس، از آنجاییکه من اسکریپت را با استفاده از SQLCMD اجرا کردم، تابع DATEDIFF را در انتهای آن قرار دادم. این تابع به من اجازه می دهد بفهمم کل اجرا چند ثانیه طول می کشد (برای نوع ویندوز، می توانم به سادگی نگاه کلی به تایمر در SQL Server Management Studio داشته باشم).[/vc_column_text][vc_column_text]
SET NOCOUNT ON GO DECLARE @StartTime DATETIME; DECLARE @i INT; DECLARE @limit INT; SET @StartTime = GETDATE(); SET @i = 0; SET @limit = 1000; WHILE(@i < @limit) BEGIN INSERT INTO test.dbo.ubuntu VALUES('XXXX'); SET @i = @i + 1 END SELECT DATEDIFF(SECOND,@StartTime,GETDATE()) AS 'Elapsed Seconds';
کل رشته 1,000,000 کاراکتری به جای «XXXX» می رود. من آن را فقط برای زیباتر شدن در این پست قرار می دهم.
SET NOCOUNT ON GO DECLARE @StartTime DATETIME; DECLARE @i INT; DECLARE @limit INT; SET @StartTime = GETDATE(); SET @i = 0; SET @limit = 1000; WHILE(@i < @limit) BEGIN INSERT INTO test.dbo.ubuntu VALUES('XXXX'); SET @i = @i + 1 END SELECT DATEDIFF(SECOND,@StartTime,GETDATE()) AS 'Elapsed Seconds';
اسکریپت برای اجرای دستور DELETE
SET NOCOUNT ON GO DECLARE @StartTime DATETIME; SET @StartTime = GETDATE(); DELETE FROM test.dbo.ubuntu; SELECT DATEDIFF(SECOND,@StartTime,GETDATE()) AS 'Elapsed Seconds';
[/vc_column_text][vc_empty_space height=”20px”][vc_column_text]همه اندازه ها بر حسب مگابایت بیان شده است. تمام اندازه گیری های زمان بندی بر حسب ثانیه بیان شده است.[/vc_column_text][vc_column_text]
INSERT Time | 1,000 records | 5,000 records | 10,000 records | 25,000 records | 50,000 records |
Linux | 4 | 23 | 43 | 104 | 212 |
Windows | 4 | 28 | 172 | 531 | 186 |
Size (MDF) | 1,000 records | 5,000 records | 10,000 records | 25,000 records | 50,000 records |
Linux | 264 | 1032 | 2056 | 5128 | 10184 |
Windows | 264 | 1032 | 2056 | 5128 | 10248 |
Size (LDF) | 1,000 records | 5,000 records | 10,000 records | 25,000 records | 50,000 records |
Linux | 104 | 264 | 360 | 552 | 148 |
Windows | 136 | 328 | 392 | 456 | 584 |
DELETE Time | 1,000 records | 5,000 records | 10,000 records | 25,000 records | 50,000 records |
Linux | 1 | 1 | 74 | 215 | 469 |
Windows | 1 | 63 | 126 | 357 | 396 |
DELETE Size (LDF) | 1,000 records | 5,000 records | 10,000 records | 25,000 records | 50,000 records |
Linux | 136 | 264 | 392 | 584 | 680 |
Windows | 200 | 328 | 392 | 456 | 712 |
[/vc_column_text][vc_empty_space height=”20px”][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
نتیجه های کلیدی
- اندازه MDF در کل آزمایش تقریباً ثابت بود، در پایان کمی متفاوت بود (اما چیز خیلی عجیبی نبود).
- زمان بندی INSERTها در لینوکس در اکثر موارد بهتر بود، به جز موارد پایانی که ویندوز “پیروز شد”.
- پس از هر دور INSERT، اندازه فایل گزارش تراکنش در لینوکس بهتر مدیریت می شد.
- زمان بندی DELETEها در لینوکس در اکثر موارد بهتر بود، به جز موارد انتهایی که ویندوز بهتر بود. (جالب است که ویندوز در دور نهایی INSERT نیز برنده شد).
- اندازه فایل های گزارش تراکنش ها پس از هر دور DELETE، از نظر فراز و نشیب بین هر دو تقریباً یکسان بود.
- من دوست داشتم با 100000 ردیف تست کنم، اما فضای دیسک کمی داشتم، بنابراین آن را روی 50000 گذاشتم.
[/vc_column_text][vc_empty_space height=”20px”][vc_column_text]
نتیجه
بر اساس نتایج به دست آمده از این آزمایش، می توانم بگویم هیچ دلیل محکمی برای ادعای اینکه نوع لینوکس به طور تصاعدی بهتر از نسخه ویندوزی خود عمل می کند وجود ندارد. البته، این به هیچ وجه یک آزمون رسمی نیست که بتوانید چنین تصمیمی را اتخاذ کنید. با این حال، خود تمرین برای من به اندازه کافی جالب بود.
حدس میزنم که SQL Server 2019 برای ویندوز به دلیل رندر رابط کاربری گرافیکی در پس زمینه که در سمت سرور اوبونتو انجام نمی شود، گاهی اوقات کمی عقب می افتد (نه خیلی).
اگر به شدت به ویژگی ها و قابلیت هایی که مختص ویندوز هستند (حداقل در زمان نگارش این مقاله) تکیه می کنید، حتماً آن را دنبال کنید. در غیر این صورت، به سختی می توانید انتخاب بدی را با انتخاب یکی از دیگری انجام دهید.[/vc_column_text][vc_empty_space height=”20px”][/vc_column][/vc_row]