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

SQLServer2014の探索SELECTINTOParallelism

    SQL Server 2014 CTP1は数週間前からリリースされており、メモリが最適化されたテーブルと更新可能な列ストアインデックスについてかなりの報道があったことでしょう。これらは確かに注目に値しますが、この投稿では、新しいSELECT…INTO並列処理の改善について調べたいと思いました。この改善は、すぐに使用できる変更の1つであり、見た目からすると、そのメリットを享受するためにコードを大幅に変更する必要はありません。私の調査は、バージョンMicrosoft SQL Server 2014(CTP1)– 11.0.9120.5(X64)、EnterpriseEvaluationEditionを使用して実行されました。

    並列SELECT…INTO

    SQL Server 2014では、並列対応のSELECT ... INTOが導入されています データベースとこの機能をテストするために、AdventureWorksDW2012データベースと61,847,552行を含むバージョンのFactInternetSalesテーブルを使用しました(これらの行を追加するのは私が担当しました。デフォルトではデータベースに付属していません)。

    この機能は、CTP1の時点で、データベース互換性レベル110を必要とするため、テストの目的で、データベースを互換性レベル100に設定し、最初のテストで次のクエリを実行しました。

    SELECT  [ProductKey],
            [OrderDateKey],
            [DueDateKey],
            [ShipDateKey],
            [CustomerKey],
            [PromotionKey],
            [CurrencyKey],
            [SalesTerritoryKey],
            [SalesOrderNumber],
            [SalesOrderLineNumber],
            [RevisionNumber],
            [OrderQuantity],
            [UnitPrice],
            [ExtendedAmount],
            [UnitPriceDiscountPct],
            [DiscountAmount],
            [ProductStandardCost],
            [TotalProductCost],
            [SalesAmount],
            [TaxAmt],
            [Freight],
            [CarrierTrackingNumber],
            [CustomerPONumber],
            [OrderDate],
            [DueDate],
            [ShipDate]
    INTO dbo.FactInternetSales_V2
    FROM dbo.FactInternetSales;

    テストVMでのクエリ実行時間は3分19秒で、実際に作成されたクエリ実行プランは次のとおりです。

    予想どおり、SQLServerはシリアルプランを使用しました。また、スキャンされたテーブルに非クラスター化列ストアインデックスが含まれていることにも注意してください(他のテストで使用するためにこの非クラスター化列ストアインデックスを作成しましたが、クラスター化列ストアインデックスクエリの実行プランについても後で説明します)。プランは並列処理を使用せず、ColumnstoreIndexScanはバッチ実行モードの代わりに行実行モードを使用しました。

    次に、データベースの互換性レベルを変更しました(CTP1にはまだSQL Server 2014の互換性レベルがないことに注意してください):

    USE [master];
    GO
    ALTER DATABASE [AdventureWorksDW2012] SET COMPATIBILITY_LEVEL = 110;
    GO

    FactInternetSales_V2テーブルを削除してから、元のSELECT ... INTOを再実行しました。 手術。今回のクエリ実行時間は1分7秒で、実際のクエリ実行プランは次のとおりです。

    現在、並行計画があり、AdventureWorksDW2012のデータベース互換性レベルを変更するだけで済みました。私のテストVMには4つのvCPUが割り当てられており、クエリ実行プランは4つのスレッドに行を分散しています:

    非クラスター化列ストアインデックススキャンは、並列処理を使用している間、バッチ実行モードを使用しませんでした。代わりに、行実行モードを使用しました。

    これまでのテスト結果を示す表は次のとおりです。

    スキャンタイプ 互換性レベル 並列SELECT…INTO 実行モード 期間
    非クラスター化列ストアインデックススキャン 100 いいえ 3:19
    非クラスター化列ストアインデックススキャン 110 はい 1:07


    次のテストとして、非クラスター化列ストアインデックスを削除し、SELECT ... INTOを再実行しました。 データベース互換性レベル100と110の両方を使用してクエリを実行します。

    互換性レベル100のテストの実行には5分44秒かかり、次の計画が生成されました。

    シリアルクラスター化インデックススキャンは、シリアル非クラスター化列ストアインデックススキャンよりも2分25秒長くかかりました。

    互換性レベル110を使用すると、クエリの実行に1分55秒かかり、次のプランが生成されました。

    並列非クラスター化列ストアインデックススキャンテストと同様に、並列クラスター化インデックススキャンは4つのスレッドに行を分散します:

    次の表は、前述の2つのテストをまとめたものです。

    スキャンタイプ 互換性レベル 並列SELECT…INTO 実行モード 期間
    クラスター化インデックススキャン 100 いいえ 行(N / A) 5:44
    クラスター化インデックススキャン 110 はい 行(N / A) 1:55


    それで、クラスター化列ストアインデックス(SQL Server 2014の新機能)のパフォーマンスについて疑問に思ったので、既存のインデックスを削除して、FactInternetSalesテーブルにクラスター化列ストアインデックスを作成しました。また、クラスター化列ストアインデックスを作成する前に、テーブルに定義されている8つの異なる外部キー制約を削除する必要がありました。

    SELECT ... INTOを比較しているので、議論はやや学術的になります そもそもクラスター化列ストアインデックスを提供しなかったデータベース互換性レベルでのパフォーマンス、およびデータベース互換性レベル100での非クラスター化列ストアインデックスの以前のテストも行いませんでしたが、全体的なパフォーマンス特性を確認して比較するのは興味深いことです。

    >
    CREATE CLUSTERED COLUMNSTORE INDEX [CCSI_FactInternetSales] 
    ON [dbo].[FactInternetSales] 
    WITH (DROP_EXISTING = OFF);
    GO

    余談ですが、61,847,552百万行のテーブルにクラスター化列ストアインデックスを作成する操作には、4つの使用可能なvCPU(操作はそれらすべてを活用)、4GBのRAM、およびOCZVertexSSD上の仮想ゲストストレージを使用して11分25秒かかりました。その間、CPUは常にペグされていませんでしたが、山と谷が表示されていました(以下に示すCPUアクティビティの60秒のサンプリング):

    クラスタ化された列ストアインデックスが作成された後、2つのSELECT ... INTOを再実行しました テスト。互換性レベル100のテストの実行には3分22秒かかり、計画は期待どおりに連続したものでした(SQL Server 2014 CTP1の時点で、クラスター化された列ストアインデックススキャン以降の計画のSQL ServerManagementStudioバージョンを示しています、Plan Explorerによってまだ完全には認識されていません):

    次に、データベースの互換性レベルを110に変更してテストを再実行しました。今回は、クエリに1分11秒かかり、実際の実行プランは次のとおりです。

    計画では、行を4つのスレッドに分散し、非クラスター化列ストアインデックスと同様に、クラスター化列ストアインデックススキャンの実行モードは行であり、バッチではありませんでした。

    次の表は、この投稿内のすべてのテストをまとめたものです(期間の順に、低いものから高いものへ):

    スキャンタイプ 互換性レベル 並列SELECT…INTO 実行モード 期間
    非クラスター化列ストアインデックススキャン 110 はい 1:07
    クラスター化列ストアインデックススキャン 110 はい 1:11
    クラスター化インデックススキャン 110 はい 行(N / A) 1:55
    非クラスター化列ストアインデックススキャン 100 いいえ 3:19
    クラスター化列ストアインデックススキャン 100 いいえ 3:22
    クラスター化インデックススキャン 100 いいえ 行(N / A) 5:44


    いくつかの所見:

    • 並列のSELECT ... INTOの違いがわからない 非クラスター化列ストアインデックスとクラスター化列ストアインデックスに対する操作は、統計的に有意です。もっとテストをする必要がありますが、RTMまでそれらを実行するのを待つと思います。
    • 並列のSELECT ... INTOと言っても過言ではありません。 クラスター化インデックス、非クラスター化列ストア、およびクラスター化列ストアインデックスのテスト全体で、同等のシリアルを大幅に上回りました。

    これらの結果は製品のCTPバージョンのものであり、私のテストはRTMによって動作が変化する可能性があるものと見なす必要があるため、スタンドアロンの期間とシリアルとパラレルの期間の比較にはあまり関心がありませんでした。条件。

    一部のパフォーマンス機能では、大幅なリファクタリングが必要ですが、SELECT ... INTOの場合 改善のために、私がしなければならなかったのは、メリットを確認し始めるためにデータベースの互換性レベルを上げることだけでした。これは間違いなく私が感謝していることです。


    1. MySQLエラー1064構文ですが、すべて問題ないようです

    2. APPEND_ONLY_STORAGE_INSERT_POINTラッチ

    3. ディメンションのディメンション:データウェアハウスの最も一般的なディメンションテーブルタイプの概要

    4. MySQLの数値にはTOPX(または下)パーセントを選択します