web-dev-qa-db-ja.com

SQLサーバーのSSDのパフォーマンスが遅い

私はアイデアが足りないので、あなたの助けを求めています。インターネットでどれだけ検索しても原因がわからない奇妙な問題があります。

事は、私は2つのラップトップを持っている:

l1:HDDとKingston HyperX Fury SATA-III SSD(240G)

l2:HDDおよびSamsung 960 evo、nvme SSD(500G)

また、データベースのパフォーマンスをテストする手順があります。この手順では、10,000、100,000の数の3つの異なるテーブルから挿入、選択、削除を行います。

l2はl1の後に購入され、データベースを含め、l1にあるすべてのものをl2に移行しようとしました。パフォーマンスプロシージャを実行した後、奇妙なことに気づき、l1の方がl1の場合よりも多く使用されていました。テーブルに10,000行を挿入する例として、l1は1秒かかり、l2は28秒かかります。もちろん、l2で10万回の挿入を試す忍耐力はありませんでした。l1では40秒しかかかりません。

だから、原因の根源を見つけようとした。タスクマネージャー(Windows 10を使用しています)の[パフォーマンス]タブを開き、挿入しようとすると、SSDは200kb/sでのみ書き込みを行っているのに対し、l1のSSDは4.4MB/sで書き込みを行っていることがわかりました。

l2

enter image description here

もちろん、SSDが故障している可能性があるため、3つのベンチマークを使用して確認しました。私が最初に使用したのは、Samsung Magician、CrystalDiskMark、AS SSD Benchmarkでした。これら3つのベンチマークのすべてで問題はなく、私のSSDは本来あるべき速度で動作しています。私のドライバはすべて最新であり、ssdのファームウェアは最新のものであることに注意する必要があります。 SQL Serverを再インストールして、エディションをEnterpriseからDeveloper(l1で使用しているDeveloper)に変更してみました。

私が試したもう1つのことは、データベースを切り離すことでした。それを他のドライブに移動し、再び取り付けます。それを見つけるには、SSDよりもうまく機能します。

各パフォーマンスチェックの結果(挿入10,000回+選択+削除):(IncepeLa = StartsAt、SeIncheieLa = EndsAt)

sSD上のl2: enter image description here

hDD上のl2: enter image description here

sSDのl1: enter image description here

結局のところ、問題は... HDDよりも優れているはずの部分でSQL Serverのパフォーマンスが大幅に低下するのはなぜですか。

編集:

enter image description here

編集2:

ストール時間に関して興味深いことを示す別の画像を追加しました。 enter image description here

醜いコード:

declare @id_test int
declare @name_test nvarchar(50)

declare ctest cursor
for
    select CodTest, Nume from Teste;
open ctest
    fetch next from ctest into @id_test, @name_test;
    while @@FETCH_STATUS = 0 begin
        if @name_test = 'insert'
        -- @name_test TesteTabele
        begin
            declare @t_t_cte int
            declare @t_t_cta int
            declare @t_t_nr int
            declare @t_t_p int

            insert into RulariTeste (Descriere, IncepeLa, SeIncheieLa) values ('Add in table', SYSDATETIME(), null);
            declare c_t_t cursor
            for
                select * from TesteTabele
            open c_t_t
                fetch next from c_t_t into @t_t_cte, @t_t_cta, @t_t_nr, @t_t_p
                while @@FETCH_STATUS = 0 begin
                    insert into RulariTesteTabele (CodRulareTest, CodTabel, IncepeLa, SeIncheieLa) values (@t_t_cte, @t_t_cta, SYSDATETIME(), 0);
                    exec('addfields' + @t_t_cta + ' ' + @t_t_nr);
                    update RulariTesteTabele set SeIncheieLa = SYSDATETIME() where CodRulareTest = @t_t_cte and CodTabel = @t_t_cta;
                    fetch next from c_t_t into @t_t_cte, @t_t_cta, @t_t_nr, @t_t_p
                end
            close c_t_t
            deallocate c_t_t
            update RulariTeste set SeIncheieLa = SYSDATETIME() where @id_test = CodRulareTest;
        end
        else if @name_test = 'select'
        -- @name_test TesteViewuri
        begin
            declare @t_v_ct int
            declare @t_v_cv int

            insert into RulariTeste (Descriere, IncepeLa, SeIncheieLa) values ('Select view', SYSDATETIME(), null);
            declare c_t_v cursor
            for
                select * from TesteViewuri
            open c_t_v
                fetch next from c_t_v into @t_v_ct, @t_v_cv
                while @@FETCH_STATUS = 0 begin
                    insert into RulariTesteViewuri (CodRulareTest, CodView, IncepeLa, SeIncheieLa) values (@t_v_ct, @t_v_cv, SYSDATETIME(), 0);
                    select * from (select Nume from Viewuri where CodView = @t_v_cv) as aview;
                    update RulariTesteViewuri set SeIncheieLa = SYSDATETIME() where CodRulareTest = @t_v_ct and CodView = @t_v_cv;
                    fetch next from c_t_v into @t_v_ct, @t_v_cv
                end
            close c_t_v
            deallocate c_t_v
            update RulariTeste set SeIncheieLa = SYSDATETIME() where @id_test = CodRulareTest;
        end
        else if @name_test = 'delete'
        begin
            insert into RulariTeste (Descriere, IncepeLa, SeIncheieLa) values ('Delete from table', SYSDATETIME(), null);
            delete from topic_follows;
            delete from topics;
            delete from users;
            update RulariTeste set SeIncheieLa = SYSDATETIME() where CodRulareTest = (select TOP(1) CodRulareTest from RulariTeste order by CodRulareTest desc);
        end
        fetch next from ctest into @id_test, @name_test
    end
close ctest;
deallocate ctest;

Addfields関数は、しばらくすると、テーブルのフィールドを追加することになっています。

編集3:問題をより明確にするために、使用されているアルゴリズムについてではありません。 10,000個の値を追加するしばらくの間、デモを行います。 dbがSSDにあるときと、dbがHDDにあるときは、このテストではl2のみを使用します。

それが私が投稿できる最後の画像であるため、両方で構成される画像(8つを超える画像を投稿するという10の評判はありません) enter image description here

お気づきのように、DBがHDDにある場合は2秒で挿入を実行しますが、SSDにある場合は27秒で挿入を実行します。

7
Tigrex

わかった、私はそれを解決した。いろいろなものを探していろいろ試してみて、ようやく終わりました。

私は最初の質問で「すべてのドライバーは最新の状態です」と書きましたが、これは私からの嫌な嘘のように見えます。申し訳ありませんが、ファームウェアのみを更新し、ドライバーも更新するというビジョンを持っていました。

Samsungの元のサイトから最新のドライバーをインストールすることですべてが解決されたようです。私見私はドライバーの変更よりもこのような大幅な変更を期待していませんでした。

私が以前持っていたドライバーは、Microsoftが所有するNVMeドライバーの下のツール「Samsung Magician」に示されていました。ドライバーをインストールすると、Samsungと表示されます。

私は再び誤った情報をお詫びします。サポートをしてくれたBrent Ozarに感謝します。それがなければ、このクエストを長い間見捨てて、「それに対処する」だけでした。

4
Tigrex

パフォーマンスの問題が発生した場合は常に、「私の一番上の待機タイプは何ですか?」待機統計は、SQL Serverが待機しているものを示します。

私は sp_BlitzFirst で待機を測定するのが好きです(免責事項:私が書いたものです)。これは無料のオープンソースです。MITこのように待つ:

EXEC sp_BlitzFirst @Seconds = 60, @ExpertMode = 1;

これは、待機の60秒のサンプルを取ります。待機統計セクションのスクリーンショットを投稿してください。サーバーが待機しているものを説明できる場合があります。

更新:追加したスクリーンショットでは、60秒の間に2秒のWRITELOG待機が示されています。基本的に、SQL Serverはそれほど待機していません。私の推測では、シミュレートされたワークロードには、シリアルシングルトンアクティビティが含まれます。つまり、負荷生成ツールの1つのスレッドから、一度に1行ずつ作業します。これは、ワークロードをシミュレートするための優れた方法ではありません。一度に多くのアクティビティが発生し、一度に複数の行のアクティビティを実行するマルチスレッドの負荷生成ツールを使用する必要があります。

7
Brent Ozar