都内で働くSEの技術的なひとりごと / Technical soliloquy of System Engineer working in Tokyo

都内でサラリーマンやってます。SQL Server を中心とした (2023年からは Azure も。) マイクロソフト系(たまに、OSS系などマイクロソフト以外の技術も...)の技術的なことについて書いています。日々の仕事の中で、気になったことを技術要素関係なく気まぐれに選んでいるので記事内容は開発言語、インフラ等ばらばらです。なお、当ブログで発信、発言は私個人のものであり、所属する組織、企業、団体等とは何のかかわりもございません。ブログの内容もきちんと検証して使用してください。英語の勉強のため、英語の

統計情報について簡単に説明してみる

今回やることを説明してみる

 統計情報について、理解してない人多いですよね? SQL Serverのクエリオプマイザはコストベースで実装されいます。そのため、『統計情報』は非常に重要なものです。SQL Server がこの統計情報をどのようなに保持しているかは....下記のブログを参照してください。ryuchan.hatenablog.com
ryuchan.hatenablog.com
ryuchan.hatenablog.com

 上記のブログを参照すれば(今回説明する気なしw)、インデックスが作成されていたとしても、データの分布、密度などが判断できないと高速なクエリの実行ができないことがわかるかと思います。

使用する環境を説明してみる

 My Lenovo with SQL Server 2014 です。

試してみる

 実際試してみましょう。データベースは、AdventureWorks2014 を使用します。使用するテーブルは下記の通りです。
f:id:koogucc11:20150411181647p:plain

 今回は実験のため、まず統計情報のサンプリング数を 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

f:id:koogucc11:20150411183258p:plain

 上記の処理が完了したら、下記のクエリを発行してみます。

SELECT [WorkOrderID]
      ,[ProductID]
      ,[OrderQty]
      ,[StockedQty]
      ,[ScrappedQty]
      ,[StartDate]
      ,[EndDate]
      ,[DueDate]
      ,[ScrapReasonID]
      ,[ModifiedDate]
FROM [AdventureWorks2014].[Production].[WorkOrder]
WHERE ProductID = 725

 実行プランを見ると、何やら警告のようなものが表示されていますね。
f:id:koogucc11:20150411185546p:plain
 
 内容を参照してみましょう。実際の行数と予測行数が 2倍以上の差がありますね。着目してほしいのは、警告部分です。統計情報がないとの警告です。統計情報が存在しないため、正確なデータ分布をオプティマイザが判断できないためにこのような現象が発生しています。
f:id:koogucc11:20150411190519p:plain

 オプティマイザが正確な判断をできるように下記のような 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

f:id:koogucc11:20150411191240p:plain

 上記の処理が完了したら、再度下記のクエリを実行します。

SELECT [WorkOrderID]
      ,[ProductID]
      ,[OrderQty]
      ,[StockedQty]
      ,[ScrappedQty]
      ,[StartDate]
      ,[EndDate]
      ,[DueDate]
      ,[ScrapReasonID]
      ,[ModifiedDate]
FROM [AdventureWorks2014].[Production].[WorkOrder]
WHERE ProductID = 725

 
 実行プランを参照すると、警告が消えています。
f:id:koogucc11:20150411191503p:plain 

 実際の行数と予測行数も完全に一致しています。その他のコストなども減少していますね。
f:id:koogucc11:20150411191720p:plain

終わりに何か言ってみる

 統計は大事です。しっかり勉強しましょう。

※ BI も勉強したいですねぇ。

SQL Server 2014. Enhancements, Bussines Intelligence and Big Data

SQL Server 2014. Enhancements, Bussines Intelligence and Big Data