sql >> データベース >  >> RDS >> Sqlserver

Linux上のMSSQLServerとWindowsのパフォーマンステストで違いを見つける

    Linux用のSQLServer2017のリリース以来、Microsoftはゲーム全体を大幅に変更しました。これにより、有名なリレーショナルデータベースのまったく新しい可能性が生まれ、それまでWindowsスペースでしか利用できなかったものが提供されました。

    純粋主義者のDBAは、すぐに使えるSQL Server 2019 Linuxバージョンには、Windows版に関して、機能に関していくつかの違いがあることをすぐに教えてくれることを知っています。

    • SQLServerエージェントなし
    • ファイルストリームなし
    • システム拡張ストアドプロシージャ(xp_cmdshellなど)はありません

    しかし、私は「両方ができることと、少なくともある程度は比較できるとしたらどうなるだろうか」と考えるほど興味をそそられました。そこで、いくつかのVMでトリガーを引き、いくつかの簡単なテストを準備し、データを収集して提示しました。どうなるか見てみましょう!

    最初の考慮事項

    各VMの仕様は次のとおりです。

    • Windows
      • Windows 10 OS
      • 4つのvCPU
      • 4 GB RAM
      • 30 GB SSD
    • Linux
      • Ubuntu Server 20.04 LTS
      • 4つのvCPU
      • 4 GB RAM
      • 30 GB SSD

    SQL Serverバージョンでは、両方のオペレーティングシステム用に最新のものを選択しました:SQL Server 2019 Developer Edition CU10

    各デプロイメントで有効にされたのは、インスタントファイル初期化(Linuxではデフォルトで有効、Windowsでは手動で有効)のみでした。それ以外は、残りの設定はデフォルト値のままでした。

    • Windowsでは、インストールウィザードを使用してインスタントファイル初期化を有効にすることを選択できます。

    この投稿では、Linuxでのインスタントファイル初期化作業の具体性については説明しません。ただし、後で読むことができる専用の記事へのリンクを残しておきます(技術的な面で少し重くなるので注意してください)。

    テストには何が含まれますか?

    1. 各SQLServer2019インスタンスで、テストデータベースを展開し、1つのフィールド(NVARCHAR(MAX))のみを含む1つのテーブルを作成しました。
    2. ランダムに生成された1,000,000文字の文字列を使用して、次の手順を実行しました。
      • *X行数をテストテーブルに挿入します。
      • INSERTステートメントの完了にかかった時間を測定します。
      • MDFおよびLDFファイルのサイズを測定します。
      • テストテーブルのすべての行を削除します。
      • **DELETEステートメントを完了するのにかかった時間を測定します。
      • LDFファイルのサイズを測定します。
      • テストデータベースを削除します。
      • テストデータベースを再作成します。
      • 同じサイクルを繰り返します。

    * Xは、1,000、5,000、10,000、25,000、および50,000行に対して実行されました。

    ** TRUNCATEステートメントがより効率的に機能することは知っていますが、ここでの私のポイントは、各OSでの削除操作に対して各トランザクションログがどの程度適切に管理されているかを証明することです。

    さらに深く掘り下げたい場合は、ランダムな文字列を生成するために使用したWebサイトに進むことができます。

    各オペレーティングシステムでのテストに使用したTSQLコードのセクションは次のとおりです。

    LinuxTSQLコード

    データベースとテーブルの作成

    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'
    

    以下のスクリーンショットは、データベースに何も保存されていない場合のデータファイルのサイズを示しています。

    インスタントファイル初期化が有効になっているかどうかを確認するためのクエリ

    SELECT 
           servicename,
           instant_file_initialization_enabled
    FROM   sys.dm_server_services
    WHERE  servicename = 'SQL Server (MSSQLSERVER)'
    

    WindowsTSQLコード

    データベースとテーブルの作成

    DROP DATABASE IF EXISTS test
    CREATE DATABASE test
        ON
    (FILENAME= 'S:\Program Files\Microsoft SQL Server\MSSQL15.WINDOWS\MSSQL\DATA\test.mdf', NAME = test, FILEGROWTH = 128MB)
    LOG ON
    (FILENAME= ''S:\Program Files\Microsoft SQL Server\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'
    

    次のスクリーンショットは、データベースに何も保存されていない場合のデータファイルのサイズを示しています。

    インスタントファイル初期化が有効になっているかどうかを確認するためのクエリ

    SELECT 
           servicename,
           instant_file_initialization_enabled
    FROM   sys.dm_server_services
    WHERE  servicename = 'SQL Server (MSSQLSERVER)'
    

    INSERTステートメントを実行するためのスクリプト:

    @limit->ここで、テストテーブルに挿入する行数を指定しました

    Linuxの場合、SQLCMDを使用してスクリプトを実行したため、最後にDATEDIFF関数を配置しました。実行全体にかかる秒数がわかります(Windowsバリアントの場合、SQL Server Management Studioのタイマーを垣間見ることができました)。

    「XXXX」の代わりに、1,000,000文字の文字列全体が使用されます。私はそれをこの投稿でうまく提示するためだけにそのように置いています。

    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';
    

    得られた結果

    すべてのサイズはMBで表されます。すべてのタイミング測定値は秒単位で表されます。

    挿入時間 1,000レコード 5,000レコード 10,000レコード 25,000レコード 50,000レコード
    Linux 4 23 43 104 212
    ウィンドウズ 4 28 172 531 186
    サイズ(MDF) 1,000レコード 5,000レコード 10,000レコード 25,000レコード 50,000レコード
    Linux 264 1032 2056 5128 10184
    ウィンドウズ 264 1032 2056 5128 10248
    サイズ(LDF) 1,000レコード 5,000レコード 10,000レコード 25,000レコード 50,000レコード
    Linux 104 264 360 552 148
    ウィンドウズ 136 328 392 456 584
    削除時間 1,000レコード 5,000レコード 10,000レコード 25,000レコード 50,000レコード
    Linux 1 1 74 215 469
    ウィンドウズ 1 63 126 357 396
    DELETEサイズ(LDF) 1,000レコード 5,000レコード 10,000レコード 25,000レコード 50,000レコード
    Linux 136 264 392 584 680
    ウィンドウズ 200 328 392 456 712

    重要な洞察

    • MDFのサイズは、テスト全体でほぼ一貫しており、最後にわずかに変化しました(ただし、あまりクレイジーではありません)。
    • INSERTのタイミングは、Windowsが「ラウンドに勝った」最後の部分を除いて、ほとんどの部分でLinuxの方が優れていました。
    • トランザクションログファイルのサイズは、INSERTの各ラウンド後にLinuxでより適切に処理されました。
    • DELETEのタイミングは、Windowsが「ラウンドに勝った」最後の部分を除いて、ほとんどの部分でLinuxの方が優れていました(Windowsが最後のINSERTラウンドにも勝ったのは不思議です)。
    • DELETEの各ラウンド後のトランザクションログファイルのサイズは、2つの間の浮き沈みの点でほぼ同点でした。
    • 100,000行でテストしたかったのですが、ディスク容量が少し不足していたため、50,000行に制限しました。

    結論

    このテストから得られた結果に基づくと、LinuxのバリアントがWindowsのバリアントよりも指数関数的に優れていると主張する強い理由はないと思います。もちろん、これは決してそのような決定を下すためにあなたが根拠となることができる正式なテストではありません。しかし、演習自体は私にとって十分に興味深いものでした。

    Windows用のSQLServer2019は、バックグラウンドでのGUIレンダリングが原因で、少し遅れることがあると思います。これは、フェンスのUbuntuサーバー側では発生していません。

    (少なくともこの記事の執筆時点では)Windows専用の機能に大きく依存している場合は、ぜひそれを選択してください。そうでなければ、どちらか一方を優先することで悪い選択をすることはほとんどありません。


    1. MySQLルートパスワードをリセットする方法

    2. このクエリでページング(スキップ/テイク)機能を実装する

    3. クロス結合を使用することと、2つのテーブルの間にコンマを入れることの違いは何ですか?

    4. 説明計画と実行計画の違い