今回やることを説明してみる
統計情報について、理解してない人多いですよね? SQL Serverのクエリオプマイザはコストベースで実装されいます。そのため、『統計情報』は非常に重要なものです。SQL Server がこの統計情報をどのようなに保持しているかは....下記のブログを参照してください。ryuchan.hatenablog.com
ryuchan.hatenablog.com
ryuchan.hatenablog.com
上記のブログを参照すれば(今回説明する気なしw)、インデックスが作成されていたとしても、データの分布、密度などが判断できないと高速なクエリの実行ができないことがわかるかと思います。
使用する環境を説明してみる
My Lenovo with SQL Server 2014 です。
試してみる
実際試してみましょう。データベースは、AdventureWorks2014 を使用します。使用するテーブルは下記の通りです。
今回は実験のため、まず統計情報のサンプリング数を 0% にしてみます。
UPDATE STATISTICS Production.WorkOrder IX_WorkOrder_ProductID WITH SAMPLE 0 PERCENT GO UPDATE STATISTICS Production.WorkOrder IX_WorkOrder_ScrapReasonID WITH SAMPLE 0 PERCENT GO UPDATE STATISTICS Production.WorkOrder PK_WorkOrder_WorkOrderID WITH SAMPLE 0 PERCENT GO
上記の処理が完了したら、下記のクエリを発行してみます。
SELECT [WorkOrderID] ,[ProductID] ,[OrderQty] ,[StockedQty] ,[ScrappedQty] ,[StartDate] ,[EndDate] ,[DueDate] ,[ScrapReasonID] ,[ModifiedDate] FROM [AdventureWorks2014].[Production].[WorkOrder] WHERE ProductID = 725
実行プランを見ると、何やら警告のようなものが表示されていますね。
内容を参照してみましょう。実際の行数と予測行数が 2倍以上の差がありますね。着目してほしいのは、警告部分です。統計情報がないとの警告です。統計情報が存在しないため、正確なデータ分布をオプティマイザが判断できないためにこのような現象が発生しています。
オプティマイザが正確な判断をできるように下記のような DDL 文を実行します。
UPDATE STATISTICS Production.WorkOrder IX_WorkOrder_ProductID WITH FULLSCAN GO UPDATE STATISTICS Production.WorkOrder IX_WorkOrder_ScrapReasonID WITH FULLSCAN GO UPDATE STATISTICS Production.WorkOrder PK_WorkOrder_WorkOrderID WITH FULLSCAN GO
上記の処理が完了したら、再度下記のクエリを実行します。
SELECT [WorkOrderID] ,[ProductID] ,[OrderQty] ,[StockedQty] ,[ScrappedQty] ,[StartDate] ,[EndDate] ,[DueDate] ,[ScrapReasonID] ,[ModifiedDate] FROM [AdventureWorks2014].[Production].[WorkOrder] WHERE ProductID = 725
実行プランを参照すると、警告が消えています。
実際の行数と予測行数も完全に一致しています。その他のコストなども減少していますね。
終わりに何か言ってみる
統計は大事です。しっかり勉強しましょう。
※ BI も勉強したいですねぇ。
SQL Server 2014. Enhancements, Bussines Intelligence and Big Data
- 作者: James Braselton
- 出版社/メーカー: Createspace
- 発売日: 2014/08/02
- メディア: ペーパーバック
- この商品を含むブログを見る