...

Adaptive Server Enterprise

by user

on
Category: Documents
34

views

Report

Comments

Transcript

Adaptive Server Enterprise
クエリ・プロセッサ
Adaptive Server® Enterprise
バージョン 15.0
ドキュメント ID:DC00526-01-1500-01
改訂:2005 年 10 月
Copyright © 1987-2006 by Sybase, Inc. All rights reserved.
このマニュアルは Sybase ソフトウェアの付属マニュアルであり、新しいマニュアルまたはテクニカル・ノートで特に示
されないかぎりは、後続のリリースにも付属します。このマニュアルの内容は予告なしに変更されることがあります。こ
のマニュアルに記載されているソフトウェアはライセンス契約に基づいて提供されるものであり、無断で使用することは
できません。
このマニュアルの内容を弊社の書面による事前許可を得ずに、電子的、機械的、手作業、光学的、またはその他のいかな
る手段によっても、複製、転載、翻訳することを禁じます。
マニュアルの注文
マニュアルの注文を承ります。ご希望の方は、サイベース株式会社営業部または代理店までご連絡ください。マニュアル
の変更は、弊社の定期的なソフトウェア・リリース時にのみ提供されます。
Sybase の商標
Sybase、Sybase のロゴ、ADA Workbench、Adaptable Windowing Environment、Adaptive Component Architecture、Adaptive
Server、Adaptive Server Anywhere、Adaptive Server Enterprise、Adaptive Server Enterprise Monitor、Adaptive Server Enterprise
Replication、Adaptive Server Everywhere、Adaptive Warehouse、Afaria、Answers Anywhere、Anywhere Studio、Application
Manager、AppModeler、APT Workbench、APT-Build、APT-Edit、APT-Execute、APT-Translator、APT-Library、AvantGo
Mobile Delivery、AvantGo Mobile Inspection、AvantGo Mobile Marketing Channel、AvantGo Mobile Pharma、AvantGo Mobile
Sales、AvantGo Pylon、AvantGo Pylon Application Server、AvantGo Pylon Conduit、AvantGo Pylon PIM Server、AvantGo Pylon
Pro、Backup Server、BizTracker、ClearConnect、Client-Library、Client Services、Convoy/DM、Copernicus、Data Pipeline、
Data Workbench、DataArchitect、Database Analyzer、DataExpress、DataServer、DataWindow、DataWindow .NET、DBLibrary、dbQueue、Developers Workbench、DirectConnect、DirectConnect Anywhere、Distribution Director、e-ADK、EAnywhere、e-Biz Impact、e-Biz Integrator、E-Whatever、EC Gateway、ECMAP、ECRTP、eFulfillment Accelerator、Embedded
SQL、EMS、Enterprise Application Studio、Enterprise Client/Server、Enterprise Connect、Enterprise Data Studio、Enterprise
Manager、Enterprise SQL Server Manager、Enterprise Work Architecture、Enterprise Work Designer、Enterprise Work Modeler、
eProcurement Accelerator、EWA、Financial Fusion、Financial Fusion Server、Gateway Manager、GlobalFIX、iAnywhere、
iAnywhere Solutions、ImpactNow、Industry Warehouse Studio、InfoMaker、Information Anywhere、Information Everywhere、
InformationConnect、InternetBuilder、iScript、Jaguar CTS、jConnect for JDBC、M2M Anywhere、Mach Desktop、Mail
Anywhere Studio、Mainframe Connect、Maintenance Express、Manage Anywhere Studio、M-Business Channel、M-Business
Network、M-Business Server、MDI Access Server、MDI Database Gateway、media.splash、MetaWorks、mFolio、Mirror
Activator、MySupport、Net-Gateway、Net-Library、New Era of Networks、ObjectConnect、ObjectCycle、OmniConnect、
OmniSQL Access Module、OmniSQL Toolkit、Open Biz、Open Client、Open ClientConnect、Open Client/Server、Open Client/
Server Interfaces、Open Gateway、Open Server、Open ServerConnect、Open Solutions、Optima++、PB-Gen、PC APT Execute、
PC DB-Net、PC Net Library、PocketBuilder、Pocket PowerBuilder、Power++、power.stop、PowerAMC、PowerBuilder、
PowerBuilder Foundation Class Library、PowerDesigner、PowerDimensions、PowerDynamo、PowerScript、PowerSite、
PowerSocket、Powersoft、PowerStage、PowerStudio、PowerTips、Powersoft Portfolio、Powersoft Professional、PowerWare
Desktop、PowerWare Enterprise、ProcessAnalyst、QAnywhere、Rapport、RemoteWare、RepConnector、Replication Agent、
Replication Driver、Replication Server、Replication Server Manager、Replication Toolkit、Report-Execute、Report Workbench、
Resource Manager、RFID Anywhere、RW-DisplayLib、RW-Library、S-Designor、SDF、Search Anywhere、Secure SQL Server、
Secure SQL Toolset、Security Guardian、SKILS、smart.partners、smart.parts、smart.script、SOA Anywhere、SQL Advantage、
SQL Anywhere、SQL Anywhere Studio、SQL Code Checker、SQL Debug、SQL Edit、SQL Edit/TPU、SQL Everywhere、SQL
Modeler、SQL Remote、SQL Server、SQL Server Manager、SQL SMART、SQL Toolset、SQL Server/CFT、SQL Server/DBM、
SQL Server SNMP SubAgent、SQL Station、SQLJ、STEP、SupportNow、S.W.I.F.T. Message Format Libraries、Sybase Central、
Sybase Client/Server Interfaces、Sybase Financial Server、Sybase Gateways、Sybase IQ、Sybase MPP、Sybase SQL Desktop、
Sybase SQL Lifecycle、Sybase SQL Workgroup、Sybase User Workbench、SybaseWare、Syber Financial、SyberAssist、SybFlex、
SyBooks、System 10、System 11、System XI (logo)、SystemTools、Tabular Data Stream、TradeForce、Transact-SQL、
Translation Toolkit、UltraLite、UltraLite.NET、UNIBOM、Unilib、Uninull、Unisep、Unistring、URK Runtime Kit for
UniCode、VisualWriter、VQL、WarehouseArchitect、Warehouse Control Center、Warehouse Studio、Warehouse WORKS、
Watcom、Watcom SQL、Watcom SQL Server、Web Deployment Kit、Web.PB、Web.SQL、WebSights、WebViewer、
WorkGroup SQL Server、XA-Library、XA-Server、XcelleNet、および XP Server は、米国法人 Sybase, Inc. の商標です。
Unicode と Unicode のロゴは、Unicode, Inc. の登録商標です。
このマニュアルに記載されている上記以外の社名および製品名は、各社の商標または登録商標の場合があります。
Use, duplication, or disclosure by the government is subject to the restrictions set forth in subparagraph (c)(1)(ii) of DFARS 52.227-7013
for the DOD and as set forth in FAR 52.227-19(a)-(d) for civilian agencies.
Sybase, Inc., One Sybase Drive, Dublin, CA 94568.
目次
はじめに .................................................................................................................................................. ix
第1章
Adaptive Server におけるクエリ処理 (QP) について ........................... 1
クエリ・オプティマイザ........................................................................ 3
クエリ最適化において分析される要素 ........................................... 6
クエリ最適化のための変形 ............................................................. 7
探索引数と有用なインデックスの扱い ......................................... 11
ジョインの扱い ............................................................................. 13
最適化目標 ........................................................................................... 15
例外 ............................................................................................... 16
クエリ最適化の実行時間を制限する............................................. 16
並列処理 ............................................................................................... 17
最適化に関する問題 ............................................................................. 18
Lava クエリ実行エンジン .................................................................... 20
Lava クエリ・プラン .................................................................... 21
第2章
並列クエリ処理 (QP) ............................................................................ 27
垂直、水平、パイプライン並列処理....................................................
並列処理のメリットを利用できるクエリ.............................................
並列処理の有効化.................................................................................
number of worker processes の設定 .............................................
max parallel degree の設定...........................................................
max resource granularity の設定...................................................
max repartition degree の設定 ......................................................
max scan parallel degree の設定 ..................................................
セッション・レベルでの並列処理の制御.............................................
set コマンドの例...........................................................................
クエリの並列処理の制御......................................................................
クエリ・レベルの parallel 句の例 .................................................
並列クエリの結果が異なる場合 ...........................................................
set rowcount を使用するクエリ ....................................................
ローカル変数を設定するクエリ....................................................
並列クエリ・プランについて...............................................................
クエリ・プロセッサ
27
28
29
29
30
30
31
31
32
33
34
34
34
35
35
36
iii
目次
Adaptive Server の並列クエリ実行モデル ...........................................
exchange オペレータ ...................................................................
SQL 演算での並列処理の使用 ......................................................
パーティション排除 .....................................................................
分割スキュー ................................................................................
クエリが並列で実行されない場合 ................................................
実行時調整 ....................................................................................
実行時調整の識別と管理 ..............................................................
第3章
38
38
43
82
83
85
85
86
showplan の使用 .................................................................................. 89
クエリ・プランの表示 ......................................................................... 89
ASE 15.0 でのクエリ・プラン ..................................................... 90
文レベル出力........................................................................................ 91
Lava クエリ・プランの形状 ................................................................ 94
Lava オペレータ ........................................................................... 97
Emit オペレータ............................................................................ 97
Scan オペレータ........................................................................... 98
from cache .................................................................................... 98
from or list ..................................................................................... 98
from table ...................................................................................... 99
和集合オペレータ .............................................................................. 131
hash union .................................................................................. 131
merge union ................................................................................ 132
union all オペレータ.................................................................... 133
scalaragg オペレータ ................................................................. 134
restrict オペレータ ...................................................................... 135
sort オペレータ ........................................................................... 135
store オペレータ ......................................................................... 137
sequencer オペレータ ................................................................ 139
remscan オペレータ ................................................................... 141
scroll オペレータ......................................................................... 141
ridjoin オペレータ ....................................................................... 143
sqfilter オペレータ ...................................................................... 143
exchange オペレータ ................................................................. 144
第4章
クエリ最適化方式と見積もりの表示................................................... 147
テキスト・フォーマット・メッセージの set コマンド .....................
XML フォーマット・メッセージの set コマンド...............................
使用例 .........................................................................................
set コマンドのパーミッション ...................................................
廃止になったトレース・コマンド ..............................................
iv
147
148
151
153
153
Adaptive Server Enterprise
目次
第5章
クエリ処理 (QP) 測定基準 .................................................................. 155
クエリ処理 (QP) 測定基準とは........................................................... 155
QP 測定基準の実行 ............................................................................ 156
測定基準のアクセス ........................................................................... 156
測定基準の使用................................................................................... 156
QP 測定基準とモニタリング・テーブルのどちらを
使用すべきか........................................................................ 157
sysquerymetrics ビュー............................................................... 157
例 ................................................................................................. 158
測定基準のクリア ............................................................................... 160
第6章
抽象プラン .......................................................................................... 161
新しいオペレータとその構文 ............................................................. 162
新しいディレクティブとその構文...................................................... 165
最適化目標................................................................................... 165
最適化タイムアウト時間 ............................................................. 165
15.0 より前のオペレータのサポート ................................................. 165
複雑なクエリの例 ............................................................................... 166
測定基準 ............................................................................................. 167
ワーク・テーブルと手順 .................................................................... 167
構文上の修飾 ...................................................................................... 168
古くなった部分プラン........................................................................ 169
第7章
パフォーマンス改善のための統計値の使用 ........................................ 171
Adaptive Server で管理される統計値................................................. 171
定義 ............................................................................................. 172
統計値の重要性................................................................................... 172
統計値の更新 ...................................................................................... 173
インデックス未設定カラムへの統計値の追加 ............................ 173
update statistics コマンド ........................................................... 174
update statistics へのサンプリングの使用 .................................. 175
統計の自動更新................................................................................... 176
datachange 関数とは .................................................................. 177
自動 update statistics の設定 .............................................................. 179
Job Scheduler を使用した統計値の更新 ..................................... 179
datachange を使用した統計値の更新の例 .................................. 182
カラム統計値と統計値管理................................................................. 183
カラム統計値の作成と更新................................................................. 184
統計値の追加が有効な場合 ......................................................... 185
update statistics を使用したカラムへの統計値の追加 ................ 185
update index statistics を使用したマイナー・カラムへの
統計値の追加........................................................................ 185
update all statistics を使用した全カラムへの統計値の追加 ........ 186
クエリ・プロセッサ
v
目次
ヒストグラムのステップ数の選択 .....................................................
ステップ数が多すぎる場合のデメリット ...................................
ステップ数の選択 .......................................................................
update statistics 実行時のスキャン・タイプ、ソートの稼働条件、
ロック ..................................................................................
インデックス未設定カラムまたは非先行カラムのソート ..........
update index statistics 実行時のロック、スキャン、ソート ......
update all statistics 実行時のロック、スキャン、ソート ...........
with consumers 句の使用............................................................
update statistics が同時処理に与える影響を小さくする方法.....
delete statistics コマンドの使用 ........................................................
ロー・カウントが不正確な場合.........................................................
付録 A
vi
186
186
187
187
188
188
188
188
189
190
191
抽象プランの仕様 ................................................................................ 193
delete .................................................................................................
distinct ................................................................................................
distinct_hashing .................................................................................
distinct_sorted ....................................................................................
distinct_sorting ...................................................................................
enforce ...............................................................................................
group ..................................................................................................
group_hashing ...................................................................................
group_sorted ......................................................................................
h_join..................................................................................................
h_union_distinct .................................................................................
hints....................................................................................................
insert ..................................................................................................
join......................................................................................................
m_join.................................................................................................
m_union_all........................................................................................
m_union_distinct ................................................................................
nl_join.................................................................................................
rep_xchg ............................................................................................
scalar_agg..........................................................................................
sequence............................................................................................
sort .....................................................................................................
store ...................................................................................................
store_index.........................................................................................
union ..................................................................................................
union_all.............................................................................................
update ................................................................................................
use optgoal.........................................................................................
use opttimeoutlimit .............................................................................
values.................................................................................................
xchg....................................................................................................
193
194
197
199
201
203
204
206
207
209
210
212
213
214
216
218
220
222
224
225
227
229
231
232
234
236
237
238
239
240
241
Adaptive Server Enterprise
目次
用語解説................................................................................................................................................ 243
索引....................................................................................................................................................... 251
クエリ・プロセッサ
vii
目次
viii
Adaptive Server Enterprise
はじめに
対象読者
このマニュアルは、Sybase のシステム管理者とデータベース管理者を対象
としています。
このマニュアルの内容
このマニュアルでは、Adaptive Server Enterprise のクエリ・プロセッサにつ
いて説明し、Adaptive Server でのクエリ処理 (QP) の最適化に使用する方
法について説明します。
その他の情報
•
「第 1 章 Adaptive Server におけるクエリ処理 (QP) について」では、
Adaptive Server Enterprise でのクエリ・プロセッサの強化機能について
説明します。
•
「第 2 章 並列クエリ処理 (QP)」では、Adaptive Server Enterprise での並
列クエリ処理について説明します。
•
「第 3 章 showplan の使用」では、showplan ユーティリティによって出
力されるメッセージについて説明します。
•
「第 4 章 クエリ最適化方式と見積もりの表示」では、set option および
set plan クエリ最適化方式と診断用の見積もり表示コマンドについて
説明します。
•
「第 5 章 クエリ処理 (QP) 測定基準」では、クエリの実行における経
験的な測定基準値を識別、比較する機能である、クエリ処理測定機能
について説明します。
•
「第 6 章 抽象プラン」では、Adaptive Server Enterprise の抽象プランの
変更点と追加点について説明します。
•
「第 7 章 パフォーマンス改善のための統計値の使用」では、クエリ実
行パフォーマンスの改善のための統計値の使用について説明します。
Adaptive Server Enterprise の統計の自動更新機能ついても説明します。
•
「第 A 章 抽象プランの仕様」では、抽象プランの各種仕様の詳細を説
明します。
Sybase Getting Started CD、SyBooks CD、Sybase Product Manuals Web サイ
トを利用すると、製品について詳しく知ることができます。
•
クエリ・プロセッサ
Getting Started CD には、PDF 形式のリリース・ノートとインストー
ル・ガイド、SyBooks CD に含まれていないその他のマニュアルや更
新情報が収録されています。この CD は製品のソフトウェアに同梱さ
れています。Getting Started CD に収録されているマニュアルを参照ま
たは印刷するには、Adobe Acrobat Reader が必要です (CD 内のリンク
を使用して Adobe の Web サイトから無料でダウンロードできます )。
ix
•
SyBooks CD には製品マニュアルが収録されています。この CD は製品の
ソフトウェアに同梱されています。Eclipse ベースの SyBooks ブラウザを
使用すれば、使いやすい HTML 形式のマニュアルにアクセスできます。
一部のマニュアルは PDF 形式で提供されています。これらのマニュアル
は SyBooks CD の PDF ディレクトリに収録されています。PDF ファイル
を開いたり印刷したりするには、Adobe Acrobat Reader が必要です。
SyBooks をインストールして起動するまでの手順については、Getting
Started CD の『SyBooks インストール・ガイド』、または SyBooks CD の
README.txt ファイルを参照してください。
•
Sybase Product Manuals Web サイトは、SyBooks CD のオンライン版であり、
標準の Web ブラウザを使ってアクセスできます。また、製品マニュアル
のほか、EBFs/Updates、Technical Documents、Case Management、Solved Cases、
ニュース・グループ、Sybase Developer Network へのリンクもあります。
Technical Library Product Manuals Web サイトにアクセスするには、Product
Manuals (http://www.sybase.com/support/manuals/) にアクセスしてくだ
さい。
Sybase Web サイトの技術的な資料は頻繁に更新されます。
Web 上の Sybase 製品
の動作確認情報
❖
❖
❖
製品動作確認の最新情報にアクセスする
1
Web ブラウザで Technical Documents を指定します。
(http://www.sybase.com/support/techdocs/)
2
左側のナビゲーション・バーから [Products] を選択します。
3
製品リストから製品名を選択し、[Go] をクリックします。
4
[Certification Report] フィルタを選択し、時間枠を指定して [Go] をクリッ
クします。
5
[Certification Report] のタイトルをクリックして、レポートを表示します。
コンポーネント認定の最新情報にアクセスする
1
Web ブラウザで Availability and Certification Reports を指定します。
(http://certification.sybase.com/)
2
[Search By Base Product] で製品ファミリとベース製品を選択するか、[Search
by Platform] でプラットフォームとベース製品を選択します。
3
[Search] をクリックして、入手状況と認定レポートを表示します。
Sybase Web サイト ( サポート・ページを含む ) の自分専用のビューを作成する
MySybase プロファイルを設定します。MySybase は無料サービスです。この
サービスを使用すると、Sybase Web ページの表示方法を自分専用にカスタマ
イズできます。
x
Adaptive Server Enterprise
はじめに
1
Web ブラウザで Technical Documents を指定します。
(http://www.sybase.com/support/techdocs/)
2
[MySybase] をクリックし、MySybase プロファイルを作成します。
Sybase EBF とソフト
ウェア・メンテナンス
❖
EBF とソフトウェア・メンテナンスの最新情報にアクセスする
1
Web ブラウザで Sybase Support Page (http://www.sybase.com/support)
を指定します。
2
[EBFs/Maintenance] を選択します。MySybase のユーザ名とパスワードを入
力します。
3
製品を選択します。
4
時間枠を指定して [Go] をクリックします。EBF/Maintenance リリースの一
覧が表示されます。
鍵のアイコンは、
「Technical Support Contact」として登録されていないた
め、一部の EBF/Maintenance リリースをダウンロードする権限がないこと
を示しています。未登録ではあるが、Sybase 担当者またはサポート・コン
タクトから有効な情報を得ている場合は、[Edit Roles] をクリックして、
「Technical Support Contact」役割を MySybase プロファイルに追加します。
5
規約
EBF/Maintenance レポートを表示するには [Info] アイコンをクリックしま
す。ソフトウェアをダウンロードするには製品の説明をクリックします。
次の項では、このマニュアルで使用されている表記について説明します。
SQL は自由な形式の言語で、1 行内のワード数や、改行の仕方に規則はありま
せん。このマニュアルでは、読みやすくするため、例や構文を文の句ごとに改
行しています。複数の部分からなり、2 行以上にわたる場合は、字下げしてい
ます。複雑なコマンドの書式には、修正された BNF (Backus Naur Form) 記法が
使用されています。
表 1 に構文の規則を示します。
表 1: このマニュアルでのフォントと構文規則
要素
コマンド名、プロシージャ名、ユーティリティ名、そ
の他のキーワードは sans serif フォントで表記する。
例
select
sp_configure
データベース名とデータ型は sans serif フォントで表記
する。
master データベース
ファイル名、変数、パス名は斜体で表記する。
sql.ini ファイル
column_name
変数 ( ユーザが入力する値を表す語 ) がクエリまたは
文の一部である場合は Courier フォントの斜体で表記
する。
クエリ・プロセッサ
$SYBASE/ASE ディレクトリ
select column_name
from table_name
where search_conditions
xi
要素
例
compute row_aggregate (column_name)
カッコはコマンドの一部として入力する。
2 つのコロンと等号は、構文が BNF 表記で記述されて
いることを示す。この記号は入力しない。
「~と定義さ
れている」ことを意味する。
::=
中カッコは、その中のオプションを 1 つ以上選択しな
ければならないことを意味する。コマンドには中カッ
コは入力しない。
{cash, check, credit}
角カッコは、オプションを選択しても省略してもよい [cash | check | credit]
ことを意味する。コマンドには角カッコは入力しない。
中カッコまたは角カッコの中のカンマで区切られたオ cash, check, credit
プションをいくつでも選択できることを意味する。複
数のオプションを選択する場合には、オプションをカ
ンマで区切る。
パイプまたは縦線は複数のオプションのうち 1 つだけ cash | check | credit
を選択できることを意味する。
省略記号 (...) は、直前の要素を必要な回数だけ繰り返 buy thing = price [cash | check | credit]
[, thing = price [cash | check | credit]]...
し指定できることを意味する。
この例では、製品 (thing) を少なくとも 1 つ購入 (buy) し、価
格 (price) を指定する必要があります。支払方法を選択でき
る。角カッコで囲まれた項目の 1 つを選択する。追加品目
を、必要な数だけ購入することもできる。各 buy に対して、
購入した製品 (thing)、価格 (price)、オプションで支払方法
(cash、check、credit のいずれか ) を指定します。
•
次は、オプション句のあるコマンドの構文の例です。
sp_dropdevice [device_name]
複数のオプションを持つコマンドの例を示します。
select column_name
from table_name
where search_conditions
構文では、キーワード ( コマンド ) は通常のフォントで表記し、識別子は
小文字で表記します。ユーザが提供するワードは斜体で表記します。
•
Transact-SQL コマンドの使用例は次のように表記します。
select * from publishers
•
次は、コンピュータからの出力例です。
pub_id
------0736
0877
1389
pub_name
--------------------New Age Books
Binnet & Hardley
Algodata Infosystems
city
----------Boston
Washington
Berkeley
state
----MA
DC
CA
(3 rows affected)
xii
Adaptive Server Enterprise
はじめに
こ の マ ニ ュ ア ル で は、例 に 使 用 す る 文 字 は ほ と ん ど が 小 文 字 で す が、
Transact-SQL のキーワードを入力するときは、大文字と小文字は区別されませ
ん。たとえば、SELECT、Select、select はすべて同じです。
テーブル名などのデータベース・オブジェクトの大文字と小文字を Adaptive
Server が区別するかどうかは、Adaptive Server にインストールされたソート順
によって決まります。シングルバイト文字セットを使用している場合は、
Adaptive Server のソート順を再設定することによって、大文字と小文字の区別
の取り扱い方を変更できます。詳細については、
『システム管理ガイド』を参
照してください。
アクセシビリティ機能
このマニュアルには、アクセシビリティを重視した HTML 版もあります。この
HTML 版マニュアルは、スクリーン・リーダーで読み上げる、または画面を拡
大表示するなどの方法により、その内容を理解できるよう配慮されています。
Adaptive Server 15.0 と HTML マニュアルは、連邦リハビリテーション法第 508
条のアクセシビリティ規定に準拠していることがテストにより確認されてい
ます。第 508 条に準拠しているマニュアルは通常、World Wide Web Consortium
(W3C) の Web サイト用ガイドラインなど、米国以外のアクセシビリティ・ガ
イドラインにも準拠しています。
この製品のオンライン・ヘルプは HTML でも提供され、スクリーン・リーダー
の読み上げで内容を理解できる機能があります。
注意 アクセシビリティ・ツールを効率的に使用するには、設定が必要な場合
もあります。一部のスクリーン・リーダーは、テキストの大文字と小文字を区
別して発音します。たとえば、すべて大文字のテキスト (ALL UPPERCASE
TEXT など ) はイニシャルで発音し、大文字と小文字の混在したテキスト
(Mixed Case Text など ) は単語として発音します。構文規則を発音するように
ツールを設定すると便利かもしれません。詳細については、ツールのマニュア
ルを参照してください。
Sybase のアクセシビリティに対する取り組みについては、
Sybase Accessibility
(http://www.sybase.com/accessibility) を参照してください。Sybase Accessibility
サイトには、第 508 条と W3C 標準に関する情報へのリンクもあります。
不明な点があるときは
Sybase ソフトウェアがインストールされているサイトには、Sybase 製品の保
守契約を結んでいるサポート・センタとの連絡担当の方 ( コンタクト・パーソ
ン ) を決めてあります。マニュアルだけでは解決できない問題があった場合に
は、担当の方を通して Sybase のサポート・センタまでご連絡ください。
クエリ・プロセッサ
xiii
xiv
Adaptive Server Enterprise
第
1
章
Adaptive Server におけるクエリ処理
(QP) について
この章では、Adaptive Server Enterprise のクエリ・プロセッサの概要につい
て説明します。
トピック名
クエリ・オプティマイザ
ページ
3
最適化目標
15
並列処理
17
最適化に関する問題
18
Lava クエリ実行エンジン
20
クエリ・プロセッサは、指定されたクエリを処理するように設計されてい
ます。クエリ・プロセッサによって生成されるクエリ・プランは非常に効
率が高く、最小限のリソースを使用して実行され、その結果は矛盾がなく
正確であることが保証されます。
クエリ・プロセッサは、次の情報を使用してクエリを効率的に処理します。
•
指定されたクエリ
•
クエリ内で指定されているテーブル、インデックス、カラムについて
の統計情報
•
設定可能な変数
クエリ・プロセッサがクエリを正しく処理するには、多数のステップを実
行する必要があります。図 1-1 に、クエリ・プロセッサのモジュールを示
します。
クエリ・プロセッサ
1
図 1-1: : クエリ・プロセッサのモジュール
パーサ
プリプロセッサ
オプティマイザ
コード・ジェネレータ
手続き型実行エンジン
2
クエリ実行
エンジン
•
パーサは、SQL 文のテキストを内部的表現 ( クエリ・ツリーと呼びます )
に変換します。
•
プリプロセッサは、サブクエリやビューなどを持つ SQL 文のクエリ・ツ
リーを、より効率的なクエリ・ツリーに変形します。
•
オプティマイザは、SQL 文を実行するための演算の組み合わせの候補を
分析し ( ジョイン順、アクセスおよびジョインの方法、並列処理 )、代替
案のコスト見積もりに基づいて効率の良いものを 1 つ選択します。
•
コード・ジェネレータは、オプティマイザによって生成されたクエリ・プ
ランを、クエリ実行エンジンに適したフォーマットに変換します。
•
手続き型エンジンは、create table、execute procedure、declare cursor な
どのコマンド文を直接実行します。データ操作言語 (DML) 文、たとえば
select、insert、delete、update の場合は、すべてのクエリ・プランに対す
る実行環境をエンジンがセットアップし、クエリ実行エンジンを呼び出し
ます。
•
クエリ実行エンジンは、コード・ジェネレータによって生成されたクエ
リ・プラン内で指定されている順序付きステップを実行します。
Adaptive Server Enterprise
第1章
Adaptive Server におけるクエリ処理 (QP) について
クエリ・オプティマイザ
クエリ・オプティマイザは、オンライン・トランザクション処理 (OLTP) およ
び業務的意思決定支援システム (DSS) の環境のスピードと効率を向上させま
す。実際のクエリ環境に最も適した最適化方式を選択することができます。
クエリ・オプティマイザはセルフチューニング機能を備えているので、以前の
バージョンの Adaptive Server Enterprise に比べて介入の数が少なくなります。操
作のステップ間の実体化のためにワークテーブルを利用する頻度は高くあり
ませんが、ハッシュ操作やマージ操作の方が効率的であるとクエリ・オプティ
マイザが判断した場合は、使用されるワークテーブルが多くなります。
クエリ・オプティマイザの主な機能の一部を次に示します。
•
クエリのパフォーマンス向上のための新しい最適化手法とクエリ実行オ
ペレータ。たとえば、
•
group by 句や order by 句を持つクエリに対する、メモリ内ソートと
ハッシュを使用した実行中のグループ化と順序付けのオペレータの
サポート
•
hash および merge join オペレータのサポートによるジョイン演算の
効率化
•
複数のインデックスに対する述部を持つクエリのための、インデック
ス和集合方式およびインデックス交差方式
Adaptive Server Enterprise でサポートされるすべての最適化手法およびオ
ペレータの一覧については、表 1-1 を参照してください。これらの手法の
多くは、クエリ実行においてサポートされるオペレータに直接マッピング
されています。詳細については、
「Lava クエリ実行エンジン」(20 ページ )
を参照してください。
クエリ・プロセッサ
•
インデックスの選択機能の向上、特にジョインに or 句がある場合や、ジョ
インの and 探索引数 (SARG) どうしのデータ型が一致していないが互換
性がある場合
•
ジョイン・ヒストグラムを利用してジョイン・カラムのデータの偏りによ
る不正確さを防ぐことによる、コスト計算の改善
•
大規模な多方向ジョイン、およびスター/スノーフレーク・スキーマ・
ジョインのジョイン順序決定およびプラン方式における、新しいコスト・
ベースの排除とタイムアウトのメカニズム
•
データやインデックスのパーティション分割 ( 並列処理のビルディング・
ブロック ) をサポートする新しい最適化手法。特にデータ・セットが大き
い場合に効果を発揮します。
•
垂直並列処理と水平並列処理に対するクエリ最適化手法の改善。詳細につ
いては、「第 2 章 並列クエリ処理 (QP)」を参照してください。
•
問題の診断および解決機能の向上
3
クエリ・オプティマイザ
•
検索可能な XML 形式のトレース出力
•
新しい set コマンドからの詳細な診断出力。詳細については、「第 5
章 クエリ処理 (QP) 測定基準」を参照してください。
表 1-1: 最適化の手法とオペレータのサポート
4
オペレータ
hash join
説明
hash union distinct
クエリ・オプティマイザがハッシュ union distinct アルゴリ
ズムを使用できるかどうかを決定する。このアルゴリズム
は、ローの重複がほとんどない場合は非効率的である。
merge join
クエリ・オプティマイザがマージ・ジョイン・アルゴリ
ズムを使用できるかどうかを決定する。このアルゴリズ
ムは、入力が順序付けられていることを前提とする。
merge join が最も有益なのは、入力がマージ・キーの順
に並べられている ( たとえばインデックス・スキャンか
らの入力 ) 場合である。入力の順序付けのためにソート・
オペレータが必要になる場合は、merge join の有益さは
低くなる。
merge union all
クエリ・オプティマイザが union all に対してマージ・ア
ルゴリズムを使用できるかどうかを決定する。merge
union all では、結果のローの順序が union の入力と同じに
なる。merge union all が特に有益であるのは、入力デー
タが順序付けられており、親オペレータ ( たとえば merge
join) がその順序付けのメリットを利用している場合であ
る。そうでない場合は、merge union all にソート・オペ
レータが必要になり、効率が低下することがある。
merge union distinct
クエリ・オプティマイザが union に対してマージ・アルゴ
リズムを使用できるかどうかを決定する。merge union
distinct は merge union all に似ているが、重複行が残され
ない点が異なる。merge union distinct では、入力が順序付
けられている必要があり、出力も順序付けられている。
nested-loop-join
クエリ・オプティマイザがネストループ・ジョイン・アル
ゴリズムを使用できるかどうかを決定する。ジョインの方
法としては最もよく使われるタイプであり、順序付けを必
要としない単純な OLTP クエリでは最も有用である。
append union all
クエリ・オプティマイザが union all に対して付加アルゴ
リズムを使用できるかどうかを決定する。
distinct hashing
クエリ・オプティマイザが重複を除くためにハッシュ・
アルゴリズムを使用できるかどうかを決定する。重複を
除いた後の値の数が、ロー数と比較して少ない場合に非
常に効率的である。
クエリ・オプティマイザがハッシュ・ジョイン・アルゴ
リズムを使用できるかどうかを決定する。hash join は、
実行時に多くのリソースを消費する可能性があるが、有
用なインデックスを持たないカラムをジョインする場
合や、ジョインされるテーブルのロー数の積と比較し
て、ジョイン条件を満たすローの数が比較的多い場合に
有益である。
Adaptive Server Enterprise
第1章
クエリ・プロセッサ
Adaptive Server におけるクエリ処理 (QP) について
オペレータ
distinct sorted
説明
group-sorted
クエリ・オプティマイザが実行時グループ化アルゴリズ
ムを使用できるかどうかを判断する。group-sorted は、入
力ストリームがグループ化カラムでソートされているこ
とを前提としており、この順序が出力でも維持される。
distinct sorting
クエリ・オプティマイザが重複を除くためにソート・ア
ルゴリズムを使用できるかどうかを決定する。distinct
sorting が有用であるのは、インデックスがないなどの理
由で入力が順序付けられておらず、ソート・アルゴリズ
ムによる出力の順序付けが、たとえばマージ・ジョイン
においてメリットをもたらす場合である。
group hashing
クエリ・オプティマイザが集合を処理するためにグルー
プ・ハッシュ・アルゴリズムを使用できるかどうかを決
定する。
手法
multi table store ind
説明
opportunistic distinct view
非重複性を強制するときに、クエリ・オプティマイザが
より柔軟なアルゴリズムを使用できるかどうかを決定
する。
index intersection
クエリ・オプティマイザが検索領域内のクエリ・プラン
の一部として複数インデックス・スキャンの交差を使用
できるかどうかを決定する。
クエリ・オプティマイザが重複を除くためにシングルパ
ス・アルゴリズムを使用できるかどうかを決定する。
distinct sorted は、入力ストリームが順序付けられてい
ることを前提としており、そうでない場合は sort オペ
レータの数が増えることがある。
クエリ・オプティマイザが複数テーブルのジョインの結
果に対する再フォーマットを使用できるかどうかを決
定する。multi table store ind を使用すると、ワークテー
ブルの使用が増えることがある。
5
クエリ・オプティマイザ
クエリ最適化において分析される要素
クエリ・プランは、検索方式と、クエリが必要とするデータを検索するための
順序付けられた実行手順の集まりから構成されます。クエリ・プランを作成す
るときに、クエリ・オプティマイザは次のことを調べます。
•
クエリ内の各テーブルのサイズ ( ロー数とデータ・ページ数の両方 )、お
よび読み込むオブジェクト・アロケーション・マップとアロケーション・
ページの数。
•
クエリ内で使用されているテーブルとカラムに存在するインデックス、イ
ンデックスの種類、それぞれのインデックスの高さ、リーフ・ページの
数、クラスタ率。
•
クエリがインデックスでカバーされるかどうか。つまり、データ・ページ
にアクセスしなくてもインデックスのリーフ・ページからデータを取り出
すことによってクエリの要求を満たせるかどうか。Adaptive Server では、
クエリ内に where 句が含まれていない場合でも、クエリをカバーするイ
ンデックスを使用することができます。
•
インデックスのキーの密度と分布。
•
使用可能なデータ・キャッシュ ( 複数の場合もあり ) のサイズ、キャッ
シュがサポートする I/O のサイズ、使用されるキャッシュ方式。
•
物理読み込みと論理読み込みのコスト。つまり、ディスクからの物理 I/O
ページの読み込みと、メイン・メモリからの論理 I/O 読み込みのコスト。
•
ジョイン句と、最適なジョイン順およびジョインのタイプ。各ジョインに
必要なスキャンのコストと回数を検討し、I/O 回数を抑えるのにインデッ
クスが役立つかどうかを検討します。
•
ジョインの内部テーブルに有用なインデックスがない場合に、ワークテー
ブル ( 内部的なテンポラリ・テーブル ) を構築してジョイン・カラムにイ
ンデックスを作成する方が、テーブル・スキャンを繰り返すよりも高速で
あるかどうか。
•
テーブルをスキャンすることなく、インデックスを使用して値を見つけら
れる max または min 集合関数がクエリ内にあるかどうか。
•
ジョインなどのクエリの要求を満たすために、データ・ページまたはイン
デックス・ページを繰り返し使用しなければならないか、あるいはページ
をスキャンする必要が 1 回しかないため使い捨て方式を採用できるか。
各プランについて、クエリ・オプティマイザは論理 I/O と物理 I/O および CPU
処理のコストを計算して合計コストを算出します。プロキシ・テーブルがある
場合は、追加のネットワーク関連コストも計算します。計算の結果、最もコス
トの低いプランが選択されます。
6
Adaptive Server Enterprise
第1章
Adaptive Server におけるクエリ処理 (QP) について
ストアド・プロシージャとトリガが最初に実行されるときに、そのオブジェク
トが最適化され、クエリ・プランがプロシージャ・キャッシュ内に格納されま
す。キャッシュ内に使用していないプランのコピーがある場合に、他のユーザ
が同一のプロシージャを実行すると、コンパイルされたクエリ・プランは再コ
ンパイルされるのではなく、キャッシュ内にコピーされます。
クエリ最適化のための変形
クエリの解析と前処理が行われた後の、クエリ・オプティマイザによるプラン
の解析の前に、クエリの変形が行われます。これは、最適化できる句の数を増
やすためです。オプティマイザによる変形でどのように変化したかをユーザが
意識することはありませんが、showplan、dbcc(200)、statistics io、set などの
クエリ・チューニング・ツールの出力を調べることによってわかります。最適
化された探索引数の追加によって効率が向上するようなクエリを実行すると、
追加された句が明らかになります。showplan の出力では、探索引数やジョイ
ンが指定されていないテーブルの「キー:」メッセージとして表示されます。
探索引数から同等の引数への変換
オプティマイザは、探索引数に使用される形式に変換可能なクエリ句を探しま
す。表 1-2 に、これらの句を示します。
表 1-2: 句と同等な探索引数
句
between
like
変換
>= 句と <= 句に変換。たとえば、between 10 and 20 は >= 10 and <=
20 に変換される。
パターンの最初の文字が定数の場合は、like 句を大なり条件また
は小なり条件を指定したクエリに変換できる。たとえば、like
"sm%" は >= "sm" and < "sn" に変換される。
最初の文字がワイルドカードである like "%x" のような句は、イン
デックスを利用してアクセスすることができないが、ヒストグラ
ム値を使用して一致するローの数を見積もることができる。
in(values_list)
クエリ・プロセッサ
or クエリのリストに変換。たとえば、int_col in (1, 2, 3) は int_col = 1
or int_col = 2 or int_col = 3 に変換される。in リスト内の最大要素数は
1025。
7
クエリ・オプティマイザ
探索引数の推移閉包の適用 ( 可能な場合 )
オプティマイザは、探索引数に推移閉包を適用します。たとえば、次のクエリ
では、titles と titleauthor を title_id でジョインしており、titles.title_id に探索引
数が含まれています。
select au_lname, title
from titles t, titleauthor ta, authors a
where t.title_id = ta.title_id
and a.au_id = ta.au_id
and t.title_id = “T81002"
上記のクエリは、titleauthor.title_id にも探索引数が含まれているものとして、
次のように最適化されます。
select au_lname, title
from titles t, titleauthor ta, authors a
where t.title_id = ta.title_id
and a.au_id = ta.au_id
and t.title_id = “T81002”
and ta.title_id = “T81002"
このような句の追加により、クエリ・オプティマイザは、titles.title_id のイン
デックス統計値を使用して titleauthor テーブル内の一致するローの数を見積
もることができます。コストの見積もりの精度が高いほど、より効果的なイン
デックスとジョイン順を選択することができます。
等価ジョイン述部の推移閉包の適用 ( 可能な場合 )
オプティマイザは、通常の等価ジョインのジョイン・カラムに推移閉包を適用
します。次のクエリでは、t1.c11 と t2.c21 の等価ジョイン、および t2.c21 と
t3.c31 の等価ジョインを指定しています。
select *
from t1, t2, t3
where t1.c11 = t2.c21
and t2.c21 = t3.c31
and t3.c31 = 1
ジョインの推移閉包を適用しなければ、ジョイン順として検討されるのは (t1,
t2, t3)、(t2, t1, t3)、(t2, t3, t1)、(t3, t2, t1) のみとなります。t1.c11 = t3.c31 の
ジョインを追加することで、ジョイン順のリストが拡張され、候補として (t1,
t3, t2) と (t3, t1, t2) が追加されます。探索引数の推移閉包によって、t3.c31 = 1
で指定された条件がジョイン・カラム t1 と t2 に適用されます。
同様に、等価ジョインの推移閉包は、次のような or 述部を持つ等価ジョイン
にも適用されます。
select *
from R,S
where R.a = S.a
and (R.a = 5 OR S.b = 6)
8
Adaptive Server Enterprise
第1章
Adaptive Server におけるクエリ処理 (QP) について
クエリ・オプティマイザは、このクエリが、次に示すクエリと等価であると見
なします。
select *
from R,S
where R.a = S.a
and (S.a = 5 or S.b = 6)
or 述部は S のスキャンのときに評価され、or の最適化に使用されるものと考
えられます。これによって、S のインデックスが非常に効率的に使用されるこ
とになります。
ジョイン推移閉包のもう 1 つの例として、単純ではない探索引数への適用を考
えてみます。たとえば、次に示すクエリは、
select *
from R,S
where R.a = S.a and (R.a + S.b = 6)
次のように変形されます。
select *
from R,S
where R.a = S.a
and (S.a + S.b = 6)
この複雑な述部は S のスキャンのときに評価されると考えられ、早い段階で結
果セットをフィルタリングすることによるパフォーマンスの大幅な向上とな
ります。
推移閉包が使用されるのは、ここに示したような通常の等価ジョインのみで
す。次に示すようなジョインに対しては、推移閉包は行われません。
•
非等価ジョイン。例:t1.c1 > t2.c2
•
外部ジョイン。例:t1.c11 *= t2.c2、left join、right join
•
サブクエリの境界を超えるジョイン。
•
参照整合性チェックのために、またはビューの with check option で使用さ
れるジョイン。
注意 Adaptive Server Enterprise 15.0 では、sp_configure でジョイン推移閉包と
ソート・マージ・ジョインのオンとオフを切り替えるためのオプションが廃止
されました。つまり、Adaptive Server Enterprise 15.0 では、可能であれば常に
ジョイン推移閉包が適用されることになります。
クエリ・プロセッサ
9
クエリ・オプティマイザ
述部要素変形による最適化パスの追加
述部要素変形によって、クエリ・オプティマイザの選択肢の数が増えます。or
でリンクされている述部ブロックから、and でリンクされている句を抽出し
て、最適化できる句をクエリに追加します。最適化された追加の句は、クエリ
の実行に使用できるアクセス・パスが他にもあることを示します。元の or 述
部は、クエリの正当性を確認するために保持されます。
述部変形は次の手順で行われます。
1
各 or 句内の完全一致を調べる単純な述部 ( ジョイン、探索引数、in リス
ト ) が抽出されます。例では、各ブロックで完全一致を調べている次の句
が抽出されます。
t.pub_id = p.pub_id
between 句は、述部変形の前に ">= and <=" 句に変換されます。クエリ例
では、両方のクエリ・ブロックで between 15 を使用しています ( ただし
範囲の上限は異なっています )。同等の句が、手順 1 によって次のように
展開されます。
price >=15
2
同一テーブルに対する探索引数が抽出されます。展開においては、同一の
テーブルを参照しているすべての項を 1 つの述部として扱います。type と
price はどちらも titles テーブルのカラムなので、抽出後の句は次のように
なります。
(type = "travel" and price >=15 and price <= 30)
or
(type = "business" and price >= 15 and price <= 50)
3
in リストと or 句が抽出されます。1 つのブロック内に、同じテーブルに
対する複数の in リストがある場合は、最初のリストだけが抽出されます。
前述の例では、展開後のリストは次のようになります。
p.pub_id in (“P220”, “P583”, “P780”)
or
p.pub_id in (“P651", “P066", “P629”)
これらの手順どうしがオーバラップすることがあり、同じ句が抽出される
こともありますが、重複している句は除外されます。
生成された項のそれぞれについて、最適化された探索引数またはジョイン
句として使用できるかどうかを判断します。クエリ最適化に有効な項だけ
を残します。
ユーザによって指定された既存のクエリ句に、展開による新しい句を追加
します。
10
Adaptive Server Enterprise
第1章
Adaptive Server におけるクエリ処理 (QP) について
たとえば、次に示すクエリでは、最適化された句はすべて or 句で囲まれ
ています。
select p.pub_id, price
from publishers p, titles t
where (
t.pub_id = p.pub_id
and type = “travel"
and price between 15 and
and p.pub_id in (“P220",
)
or (
t.pub_id = p.pub_id
and type = “business"
and price between 15 and
and p.pub_id in (“P651",
)
30
“P583", “P780")
50
“P066", “P629")
先に説明したように、述部変形では、or でリンクされた句のブロックから and
でリンクされた句を抜き出します。カッコで囲んだすべてのブロックに共通す
る句だけが抽出されます。前述の例で、仮に、ある句が or でリンクされたブ
ロックのうちの 1 つだけにあって他のブロックにないとしたら、その句は抽出
されないことになります。
探索引数と有用なインデックスの扱い
クエリの最適化に使用できる where 句や having 句の述部と、後のクエリ処理で
返すローをフィルタするために使用される述部とを区別することは重要です。
where 句のカラムがインデックス・キーに一致するときは、探索引数を使用し
てデータ・ローへのアクセス・パスを決定することができます。インデックス
は、一致するデータ・ローを見つけて取り出すために使用されます。ローが、
データ・キャッシュの中から見つかるか、ディスクからデータ・キャッシュに
読み込まれると、残りの句がすべて適用されます。
次のクエリ例では、authors テーブルに au_lname のインデックスと city のイ
ンデックスがある場合、一致するローを見つけるために、どちらのインデック
スも使用できます。
select au_lname, city, state
from authors
where city = “Washington"
and au_lname = “Catmull"
クエリ・プロセッサ
11
クエリ・オプティマイザ
クエリ・オプティマイザは、統計値に基づいて、どのインデックスによるアク
セスが最もコストが低いかを判断します。ここで使用される統計値には、ヒス
トグラム、テーブル中のロー数、インデックスの高さ、インデックスのクラス
タ率、データ・ページのクラスタ率などがあります。最小コストでデータ・
ページにアクセスできるインデックスが選択され、そのインデックスを使用し
てクエリが実行されます。その他の句は、データ・ローがアクセスされた後に
適用されます。
不等演算子
不等演算子 < > と != に対しては、特別な処理が行われます。クエリ・オプティ
マイザは、カラムにインデックスがある場合はノンクラスタード・インデック
スをカバーするかどうかを調べて、インデックスによってクエリがカバーされ
るのであれば、非マッチング・インデックス・スキャンを行います。ただし、
インデックスによってクエリがカバーされない場合は、インデックス・スキャ
ンの実行中にロー ID ルックアップを使用してテーブルにアクセスします。
探索引数最適化の例
次に示すのは、完全に最適化できる句の例です。これらのカラムに統計値があ
る場合は、クエリが返すロー数の見積もりにその統計値を利用します。カラム
にインデックスがある場合は、データへのアクセスにそのインデックスを利用
できます。
au_lname = “Bennett"
price >= $12.00
advance > $10000 and advance < $20000
au_lname like "Ben%" and price > $12.00
次に示す探索引数は、関数インデックスがこれらのカラムに作成されなければ
最適化は不可能です。
advance * 2 = 5000
/*expression on column side
not permitted */
substring(au_lname,1,3) = "Ben" /* function on
column name */
ただし、次のように記述すると、上の 2 つの句は最適化可能になります。
advance = 5000/2
au_lname like "Ben%"
次のクエリを考えてみます。インデックスは au_lname だけにあるとします。
select au_lname, au_fname, phone
from authors
where au_lname = “Gerland”
and city = "San Francisco"
12
Adaptive Server Enterprise
第1章
Adaptive Server におけるクエリ処理 (QP) について
次に示す句は、探索引数 (SARG) となる条件を満たしています。
au_lname = “Gerland"
•
au_lname にインデックスがある。
•
カラム名に対して、関数または他のオペレーションが指定されていない。
•
演算子が、有効な探索引数演算子である。
この句は、上の条件のうち最初の条件だけは満たしていません。city カラムに
インデックスがないからです。このような場合、au_lname 上のインデックス
はクエリに使用されます。姓が一致するデータ・ページがすべてキャッシュ内
に読み込まれ、それぞれの一致したローに対して、その都市が検索基準と一致
するかどうかが調べられます。
ジョインの扱い
クエリ・オプティマイザがジョイン述部を扱う方法は、探索引数を扱うときと
同様です。つまり、統計値に基づいて、どのインデックスとジョイン方法によ
るアクセスが最もコストが低いかを判断します。ここで使用される統計値に
は、テーブル中のロー数、インデックスの高さ、インデックスのクラスタ率、
データ・ページのクラスタ率などがあります。さらに、ジョイン・ヒストグラ
ムから計算したジョイン密度の見積もり値も使用します。これは、ジョイン対
象ロー数の見積もりと、外部テーブルおよび内部テーブルのスキャンされる
ロー数の見積もりを正確に行うためです。また、最も効率的なクエリ・プラン
を生成する最適ジョイン順もクエリ・オプティマイザが決定します。次の各項
では、ジョインの処理で使用される主な手法について説明します。
ジョイン密度とジョイン・ヒストグラム
クエリ・オプティマイザがジョインに対して使用するコスト・モデルでは、
ジョイン属性のテーブル正規化ヒストグラムが使用されます。この手法では、
偏りが生じている値の正確な値 ( 頻度カウント ) が得られます。各ヒストグラ
ムからの範囲セル密度を使用して、対応する範囲セルのセル・カウントを見積
もります。
ジョイン密度は、
「ジョイン・ヒストグラム」から動的に計算されます。この
ときに、ジョイン・オペレータの両側からのヒストグラムのジョインが検討さ
れます。最初のヒストグラム・ジョインは一般に、両方の属性にヒストグラム
がある場合に 2 つのベース・テーブルの間で行われます。ヒストグラム・ジョ
インが行われるたびに、親ジョインの射影の対応する属性のヒストグラムが新
たに作成されます。
ジョイン・ヒストグラム手法を使用すると、ジョイン・カラムのデータ分布に
偏りがあっても、ジョインの選択性を正確に見積もることができ、その結果、
ジョイン順とパフォーマンスが非常に向上します。
クエリ・プロセッサ
13
クエリ・オプティマイザ
データ型が混在する場合のジョイン
ジョイン述部とインデックス・キーの間でデータ型が混在しているかどうかに
かかわらず、可能であれば必ずインデックス・ルックアップ用のキーを構築す
ることは基本的要件の 1 つです。次のようなクエリを考えてみます。
create
create
create
create
table
table
index
index
T1
T2
i1
i1
(c1 int, c2 int)
(c1 int, c2 float)
on T1(c2)
on T2(c2)
select * from T1, T2 where T1.c2=T2.c2
T1.c2 のデータ型が int で、このカラムにインデックスがあるとします。また、
T2.c2 のデータ型は float で、このカラムにもインデックスがあります。
暗黙的に変換可能なデータ型どうしであれば、ジョインの処理にインデック
ス・スキャンを使うメリットがあります。つまり、クエリ・オプティマイザ
は、外部テーブルからのカラム値を使用して内部テーブルでのインデックス・
スキャンの位置付けを行いますが、外部テーブルからのルックアップ値のデー
タ型が、内部テーブルの対応するインデックス属性のデータ型と異なっていて
もかまいません。
式と or 述部がある場合のジョイン
式と or 述部を持つジョインをクエリ・オプティマイザがどのように扱うかに
ついては、
「述部要素変形による最適化パスの追加」(10 ページ ) を参照してく
ださい。
ジョイン順の決定
クエリ・オプティマイザの主要タスクの 1 つとして、クエリ実行時に処理され
るジョインにおける関係の順序が最適になるようにジョイン・クエリのクエ
リ・プランを生成することが挙げられます。これには、時間とメモリを著しく
消費する可能性のある、複雑なプラン検索方式が必要です。クエリ・オプティ
マイザは、多数の効率的手法を使用して、最適なジョイン順を決定します。主
な手法を次に示します。
14
•
「貪欲方式」を使用して、初めに良好な順序付けを決定し、これを上限と
して、他の後続ジョイン順を排除する。貪欲方式では、ジョイン・ロー見
積もりと、ネストループ・ジョイン方式を使用して最初のジョイン順を求
めます。
•
網羅的順序付け方式は、貪欲方式に続くものです。この方式では、貪欲方
式で得られたジョイン順が、それより優れている可能性を持つジョイン順
で置き換えられます。このジョイン順では、どのようなジョイン方法も採
用される可能性があります。
Adaptive Server Enterprise
第1章
Adaptive Server におけるクエリ処理 (QP) について
•
多数の、コストベースやルールベースの排除手法を使用して、好ましくな
いジョイン順を検討対象から除外します。排除手法の重要な特徴は、常に
部分ジョイン順 ( ジョイン順候補のプレフィクス ) を最良の完全ジョイン
順と比較して、そのプレフィクスで続行するかどうかを決定することで
す。これによって、最適ジョイン順を決定するための時間が大幅に短縮さ
れます。
•
クエリ・オプティマイザは、スター型またはスノーフレーク型のスキー
マ・ジョインを認識して処理することが可能で、これらのジョイン順を最
も効率的な方法で処理します。典型的なスター・スキーマ・ジョインに
は、大きなファクト・テーブルが 1 つあります。このテーブルには等価
ジョイン述部があり、これによって多数のディメンション・テーブルと
ジョインします。ディメンション・テーブルどうしを結び付けるジョイン
述部はありません。つまり、ディメンション・テーブルどうしの間にジョ
インはありませんが、ディメンション・テーブルとファクト・テーブルの
間にはジョイン述部があります。クエリ・オプティマイザは、特別なジョ
イン順手法を使用します。この手法では、大きなファクト・テーブルを
ジョイン順の最後まで下げ、ディメンション・テーブルを前面に引き上げ
るので、非常に効率的なクエリ・プランが作成されます。ただし、スター・
スキーマ・ジョインにサブクエリや外部ジョインあるいは or 述部が含ま
れている場合は、この手法は使用されません。
最適化目標
最適化目標は、最高の最適化テクニックを使用してクエリ要求を満たす便利な
方法であり、オプティマイザの時間とリソースの最適利用が保証されます。ク
エリ・オプティマイザの 2 種類の最適化目標を、サーバ・レベル、セッショ
ン・レベル、クエリ・レベルの 3 つの層で指定することができます。
最適化目標は、目的のレベルで設定します。サーバ・レベルの最適化目標より
もセッション・レベルの最適化目標が優先され、セッション・レベルの最適化
目標よりもクエリ・レベルの最適化目標が優先されます。
次に示す最適化目標を設定することで、実際のクエリ環境に最も適した最適化
方式を選択できます。
•
allrows_mix - デフォルトの最適化目標です。混合クエリ環境では、これ
が最も実用的な最適化目標です。OLTP クエリ環境と DSS クエリ環境の
ニーズのバランスを取ることができます。
•
allrows_dss - 複雑さが中程度以上である業務的 DSS クエリを実行する
場合に最も便利な最適化目標です。現時点では、この目標は試験的に提供
されています。
サーバ・レベルでは、sp_configure を使用します。次に例を示します。
sp_configure "optimization goal", 0, "allrows_mix"
クエリ・プロセッサ
15
最適化目標
セッション・レベルでは、set plan optgoal を使用します。次に例を示します。
set plan optgoal allrows_dss
クエリ・レベルでは、select などの DML コマンドを使用します。次に例を示
します。
select * from A order by A.a plan
"(use optgoal allrows_dss)"
例外
一般に、クエリ・レベルの最適化目標は、select 文、update 文、delete 文を
使用して設定します。ただし、純粋な insert 文を使用してクエリ・レベルの最
適化目標を設定することはできませんが、insert…select 文では可能です。
クエリ最適化の実行時間を制限する
長時間実行される複雑なクエリは、最適化の時間とコストも多くなることがあ
ります。タイムアウトのメカニズムを利用すると、クエリの要求を満たすプラ
ンの作成にかける時間を制限することができます。クエリ・オプティマイザに
は、長時間実行される複雑なクエリに要する時間を制限するためのメカニズム
があり、タイムアウトを設定することで、最適化処理を適切な時点でクエリ・
プロセッサが停止できるようになっています。
クエリ・オプティマイザによる最適化処理の実行中に timeout がトリガされる
のは、次に示す状況の両方に当てはまる場合です。
•
1 つ以上の完全プランが最善プランとして残っている。
•
ユーザが設定した、パーセント単位の timeout 制限を超えている。
クエリ 1 つあたりの最適化実行時間を各レベルで制限するには、optimization
timeout limit パラメータを使用します。この値は、0 ~ 1000 の範囲で設定しま
す。optimization timeout limit パラメータは、予想クエリ実行時間に対するパー
センテージを表し、Adaptive Server はこの時間に達するまでクエリの最適化処
理を実行します。たとえば、値として 10 が指定されると、Adaptive Server は
予想クエリ実行時間の 10% をクエリの最適化に使います。同様に、値として
1000 が指定されると、Adaptive Server は予想クエリ実行時間の 1000%、つまり
10 倍をクエリ最適化に使用します。
タイムアウトの値を大きくすることは、複雑なクエリを持つストアド・プロ
シージャを最適化する場合に有益です。ストアド・プロシージャの最適化を実
行する時間を長くするとより良いプランの生成が期待できるので、最適化の時
間が長くなるというデメリットは、そのストアド・プロシージャを何度か実行
することで相殺されます。
16
Adaptive Server Enterprise
第1章
Adaptive Server におけるクエリ処理 (QP) について
タイムアウト値を小さくするのは、通常コンパイルに長時間を要する複雑なア
ドホック・クエリを短時間でコンパイルすることが必要である場合です。ただ
し、ほとんどのクエリは、デフォルト値の 10 で十分です。
最適化の timeout limit 設定パラメータをサーバ・レベルで設定するには、
sp_configure を使用します。たとえば、最適化実行時間をクエリ処理時間全体
の 10% までに制限するには、次のとおりに入力します。
sp_configure “optimization timeout limit", 10
タイムアウトをセッション・レベルで設定するには、set を使用します。
set plan opttimeoutlimit <n>
n は、0 ~ 1000 の整数です。
最適化実行時間をクエリ・レベルで設定するには、select を使用します。
select * from <table> plan "(use opttimeoutlimit <n>)"
n は、0 ~ 1000 の整数です。
表 1-3: 最適化のタイムアウト制限
要約
デフォルト値
10
値の範囲
1 ~ 1000
ステータス
動的
表示レベル
包括
必要な役割
システム管理者
並列処理
Adaptive Server では、クエリ実行に関して水平と垂直の並列処理がサポートさ
れています。垂直並列処理とは、複数のオペレータを同時に実行できるという
ことです。そのために、CPU やディスクなど、さまざまなシステム・リソー
スを必要とします。水平並列処理とは、1 つのオペレータの複数のインスタン
スを実行できるということです。インスタンスのそれぞれが、データの指定さ
れた一部分を処理します。
Adaptive Server における並列クエリ最適化の詳しい説明については、
「第 2 章
並列クエリ処理 (QP)」を参照してください。
クエリ・プロセッサ
17
最適化に関する問題
最適化に関する問題
ほとんどのクエリは、クエリ・オプティマイザによって効率的に最適化されま
すが、次に示す事項については注意が必要です。
•
統計値が更新されてから時間が経過していると、実際のデータの分布と、
クエリの最適化に使用される値が一致しないことがある。
•
指定のトランザクションによって参照されるローが、インデックス統計値
の表すパターンに合わないことがある。
•
インデックスによるアクセスの範囲が、テーブルの大部分に及ぶことが
ある。
•
where 句 ( 探索引数 ) が、最適化不可能な形式で記述されている。
•
重要なクエリに対する適切なインデックスが存在しない。
•
ストアド・プロシージャがコンパイルされた後で、基本となるテーブルに
対する重大な変更が実行された。
•
探索引数やジョイン・カラムの統計が存在しない。
このような状況においては、クエリ・オプティマイザの能力を最大限に発揮さ
せるためのベスト・プラクティスに従う必要があります。そのいくつかを次に
紹介します。
探索引数を作成する
クエリの探索引数を記述するときは、次のガイドラインに従います。
•
探索句のカラム名を指定した側に、関数、算術演算子、その他の式を指定
しないようにします。可能ならば、関数やその他の演算子を、探索句の式
の側に移動します。
•
クエリ・プロセッサが使用できるような探索引数を、できる限り多く指定
します。
•
1 つのテーブルに対して 400 個を超える述部を持つようなクエリでは、有
益である可能性の高い句をクエリの先頭近くに配置します。最適化処理で
は、各テーブルについて、先頭から 102 個の探索引数しか使用されないた
めです ( ただし、条件を満たすローの限定には、すべての探索条件が使用
されます )。
•
> ( より大きい ) を使用しているクエリは、>= ( 以上 ) を使用するように書
き換えると、パフォーマンスが向上する場合があります。たとえば、int_col
にインデックスがある場合に、次のクエリでは、このインデックスを使用
して int_col = 3 である最初の値を検出します。次に、前方にスキャンし
て、3 より大きい最初の値を検出します。int_col = 3 であるローの数が多
い場合は、int_col > 3 である最初のローを検出するためにサーバがスキャ
ンするページの数も多くなります。
select * from table1 where int_col > 3
18
Adaptive Server Enterprise
第1章
Adaptive Server におけるクエリ処理 (QP) について
このクエリは、次のように記述すれば効率が上がります。
select * from table1 where int_col >= 4
文字列や浮動小数点のデータでは、この最適化は難しくなります。
SQL 抽出テーブルを
使用する
•
showplan の出力を調べて、どのキーとインデックスが使用されているか
を確認します。
•
使用されるはずのインデックスが使用されていない場合は、表 1-1 (4 ペー
ジ ) の set コマンドの出力を参照して、そのインデックスがクエリ・プロ
セッサに認識されているかどうかを調べます。
1 つの SQL 文として表されるクエリでは、複数の SQL 文で表されるクエリよ
りも、クエリ・プロセッサが有効に活用されます。複数の SQL 文とテンポラ
リ・テーブルが必要になるようなクエリでも ( 特に、中間集計結果を保存する
ことが要求されるような場合 )、SQL 抽出テーブルを使用すると、1 ステップ
でクエリを表すことができます。次に例を示します。
select dt_1.* from
(select sum(total_sales)
from titles_west group by total_sales)
dt_1(sales_sum),
(select sum(total_sales)
from titles_east group by total_sales)
dt_2(sales_sum)
where dt_1.sales_sum = dt_2.sales_sum
この例では、集合演算の結果が SQL 抽出テーブル dt_1 と dt_2 から取得され、
この 2 つの SQL 抽出テーブル間でジョインが計算されます。すべての操作を
1 つの SQL 文で実行できます。
SQL 抽出テーブルの詳細については、『Transact-SQL ユーザーズ・ガイド』を
参照してください。
オブジェクトのサイズに
応じてチューニングする
クエリとシステムの動作を理解するためには、テーブルとインデックスのサイ
ズを知る必要があります。チューニング作業のいくつかの段階の中では、次の
目的でサイズについての情報が必要になります。
•
特定のクエリ・プランに対する statistics i/o のレポートについて理解する。
•
クエリ・プロセッサによるクエリ・プランの選択について理解する。
Adaptive Server のコストベースのオプティマイザは、アクセス・メソッド
候補のそれぞれに必要な物理 I/O と論理 I/O を見積もり、最もコストの低
いメソッドを選択します。
•
データベース・オブジェクトのサイズと、そのオブジェクトについて予想
される I/O パターンに基づいて、オブジェクトの配置を決定する。
パフォーマンスを向上させるには、データベース・オブジェクトを複数の
物理デバイスに分散することによって、ディスクの読み込みと書き込みを
均等に分散させます。
クエリ・プロセッサ
19
Lava クエリ実行エンジン
オブジェクトの配置については、
『パフォーマンス&チューニング・ガイ
ド:基本』の「データの物理的配置の制御」を参照してください。
•
パフォーマンスの変化について理解する。オブジェクト・サイズが大きく
なると、パフォーマンス特性が変化する可能性がある。たとえば、ある
テーブルが頻繁に使用され、常に 100% がキャッシュに格納されていると
します。このテーブルのサイズが拡張してキャッシュに収まらなくなる
と、このテーブルにアクセスするクエリのパフォーマンスが低下する可能
性があります。これは、特に複数のスキャンを必要とするジョインの場合
に可能性が高くなります。
•
キャパシティについて計画を立てる。新しいシステムを設計する場合も、
既存のシステムの拡張を計画する場合も、物理ディスクとメモリの計画を
立てるには、どの程度の領域が必要かを知っておく必要があります。
•
Adaptive Server Monitor Server の出力と、sp_sysmon の物理 I/O に関する
レポートについて理解する。
サイズ計算の詳細については、『システム管理ガイド』を参照してください。
Lava クエリ実行エンジン
Adaptive Server では、クエリ・プランはすべて手続き型実行エンジンに渡され
て実行されます。手続き型実行エンジンは、クエリ・プランの実行を次のよう
に推進します。
•
set、while、goto のような単純な SQL 文は直接実行します。
•
create table、create index などのユーティリティ・コマンドを実行するに
は、ユーティリティ・モジュールを呼び出します。
•
ストアド・プロシージャおよびトリガのコンテキストを設定し、実行を推
進します。
•
select 文、insert 文、delete 文、update 文のクエリ・プランを実行するた
めに、実行コンテキストを設定してクエリ実行エンジンを呼び出します。
•
カーソルの open 文、fetch 文、close 文のカーソル実行コンテキストを設
定し、クエリ実行エンジンを呼び出してこれらの文を実行します。
•
トランザクションの処理と、実行後のクリーンアップを行います。
手続き型実行エンジンの大部分は Adaptive Server 15.0 でも変更されていませ
んが、今日のアプリケーションの要求をサポートするには、新世代のクエリ実
行手法が必要です。このような要求を満たすために、クエリ実行エンジンは全
面的に書き換えられました。新しいクエリ実行エンジンとクエリ・オプティマ
イザが導入されたことで、Adaptive Server 15.0 の手続き型実行エンジンは、新
しいクエリ・オプティマイザで生成されたすべてのクエリ・プランを Lava ク
エリ実行エンジンに渡すようになっています。
20
Adaptive Server Enterprise
第1章
Adaptive Server におけるクエリ処理 (QP) について
Lava クエリ実行エンジンは、Lava クエリ・プランを実行します。クエリ・オ
プティマイザによって選択されたクエリ・プランはすべて、コンパイルされて
Lava クエリ・プランとなります。ただし、最適化されない SQL 文、たとえば
set や create は、コンパイルされて以前のバージョンの Adaptive Server と同様
のクエリ・プランが作成されます。これらのプランは、Lava クエリ実行エン
ジンによって実行されることはありません。Lava クエリ・プラン以外のプラ
ンは、手続き型実行エンジンによって実行されるか、手続き型エンジンによっ
て呼び出されるユーティリティ・モジュールによって実行されます。Adaptive
Server バージョン 15.0 では 2 種類のクエリ・プランがあり、showplan の出力
ではっきりと区別できます (「第 3 章 showplan の使用」を参照 )。
Lava クエリ・プラン
Lava クエリ・プランは、Lava オペレータから成る逆ツリーとして構築されま
す。最上位の Lava オペレータが 1 つまたは複数の子オペレータを持ち、子オ
ペレータがさらに 1 つまたは複数の子オペレータを持つことができるので、オ
ペレータの逆ツリー構造が構成されます。実際のツリーの形状と、ツリーに含
まれるオペレータは、オプティマイザによって選択されます。
次のクエリの Lava クエリ・プランの例を図 1-2 に示します。
Select o.id from sysobjects o, syscolumns c
where o.id = c.id and o.id < 2
図 1-2: Lava クエリ・プラン
Emit
NestedLoopJoin
IndexScan
sysobjects(o)
IndexScan
syscolumns(o)
このクエリの Lava クエリ・プランは、4 つの Lava オペレータで構成されます。
最上位のオペレータは Emit (Root と呼ぶこともあります ) です。このオペレー
タの役割はクエリ実行結果を送出することで、ローをクライアントに送信する
か、ローカル変数に値として割り当てます。
クエリ・プロセッサ
21
Lava クエリ実行エンジン
Emit の子オペレータは NestedLoopJoin (NLJoin) の 1 つだけです。2 つの子オ
ペレータ、(1) sysobjects のスキャンと (2) syscolumns のスキャンからのロー
を、ネストループ・ジョイン・アルゴリズムを使用してジョインします。
select 文、insert 文、delete 文、update 文はすべてオプティマイザによって最
適化されるので、これらは必ずコンパイルされて Lava クエリ・プランとなり、
Lava クエリ・エンジンによって実行されます。
SQL 文の中には、コンパイル結果が複合型のクエリ・プランになるものもあ
ります。このようなプランには複数のステップが含まれ、その一部はユーティ
リティ・モジュールによって実行されます。最後のステップは Lava クエリ・
プランです。その一例が select into 文です。select into 文をコンパイルすると、
2 ステップから成るクエリ・プランとなります。最初のステップは create table
で、文のターゲット・テーブルを作成します。2 番目のステップは、ターゲッ
ト・テーブルにローを挿入する Lava クエリ・プランです。このクエリ・プラ
ンを実行するために、手続き型実行エンジンは create table ユーティリティを
呼び出し、最初のステップを実行してテーブルを作成します。次に、手続き型
エンジンは Lava クエリ実行エンジンを呼び出して Lava クエリ・プランを実行
し、ローを選択してターゲット・テーブルに挿入します。複合型クエリ・プラ
ンを生成する SQL 文はこの他に、alter table ( ただし、データをコピーする必
要がある場合のみ ) と reorg rebuild の 2 つがあります。
Lava クエリ・プランは、BCP をサポートするという目的でも生成されて実行
されます。これまで、Adaptive Server における BCP のサポートは、BCP ユー
ティリティとして実現されていました。バージョン 15.0 では、BCP ユーティ
リティによって Lava クエリ・プランが生成され、Lava クエリ実行エンジンが
呼び出されてプランが実行されます。
Lava クエリ・プランのこの他の例については、
「第 3 章 showplan の使用」を参
照してください。
Lava オペレータ
Lava クエリ・プランは、Lava オペレータで構成されます。Lava オペレータは
それぞれ、自己完結型のソフトウェア・オブジェクトであり、クエリ・プラン
構築のためにオプティマイザによって使用される基本物理的演算の 1 つを実
装します。個々の Lava オペレータには、親オペレータから呼び出し可能な 5
つのメソッドがあります。この 5 つのメソッドとは、Acquire、Open、Next、
Close、Release で、クエリ実行の 5 つのフェーズに対応しています。すべて
の Lava オペレータに同じメソッド ( 同じ API) があるので、Lava クエリ・プラ
ンのビルディング・ブロックと同様に、オペレータどうしの入れ替えが可能で
す。たとえば、図 1-1 の NestedLoopJoin オペレータを MergeJoin オペレータ
や HashJoin オペレータで置き換えても、このクエリ・プラン内の他の 3 つの
オペレータに影響が及ぶことはありません。
Lava クエリ・プラン構築のためにオプティマイザが選択可能な Lava オペレー
タを表 1-4 に示します。
22
Adaptive Server Enterprise
第1章
Adaptive Server におけるクエリ処理 (QP) について
表 1-4: Lava オペレータ
オペレータ
BulkOp
説明
CacheScanOp
メモリ内テーブルからローを読み取ります。
DelTextOp
alter table drop のカラム処理の一部として、text ページ・
チェーンを削除する。
DeleteOp
ローカル・テーブルからローを削除する。
Lava クエリ・エンジンで行われる BCP 処理の部分を実行
します。BCP ユーティリティによって作成されるクエリ・
プランのみで使用され、オプティマイザによって作成さ
れるクエリ・プランでは使用されません。
SQL 文全体をリモート・サーバに転送 ( シッピング ) でき
ないときは、プロキシ・テーブルからローを削除する。
RemoteScanOp も参照。
EmitOp (RootOp)
クエリ実行結果のローを転送する。結果をクライアントに
送信することも、結果の値をローカル変数または fetch into
変数に割り当てることもできる。EmitOp は、常に Lava ク
エリ・プランの最上位のオペレータとなる。
EmitExchangeOp
並列処理で実行されるサブプランからの結果ローを、親
プラン・フラグメントの ExchangeOp に転送する。
EmitExchangeOp は、常に ExchangeOp の直下にある。
「第 2 章 並列クエリ処理 (QP)」を参照。
GroupSortedOp
(Aggregation)
入力ローが group-by カラムですでにソートされている場
合にベクトル集合 (group by) を実行する。
HashVectorAggOp も参照。
GroupSorted (Distinct)
重複するローを除外する。入力ローが全カラムでソートさ
れている必要がある。HashDistinctOp と SortOp (Distinct) も
参照。
HashVectorAggOp
ベクトル集合 (group by) を実行する。ハッシュ・アルゴ
リズムを使用して入力ローをグループ化するので、入力
ローの順序付けに関する要件はない。GroupSortedOp
(Aggregation) も参照。
HashDistinctOp
ハッシュ・アルゴリズムを使用して重複ローを見つける
ことで、重複ローを除外する。GroupSortedOp (Distinct)
と SortOp (Distinct) も参照。
HashJoinOp
2 つの入力ロー・ストリームのジョインを、ハッシュ・
ジョイン・アルゴリズムを使用して実行する。
HashUnionOp
2 つ以上の入力ロー・ストリームの union 演算を、ハッシュ・
アルゴリズムを使用して重複ローを検出および除外するこ
とによって実行する。
MergeUnionOp と UnionAllOp も参照。
InsScrollOp
非反映型のスクロール可能カーソルのサポートに必要
な、特別な処理を実装する。SemiInsScrollOp も参照。
InsertOp
ローカル・テーブルにローを挿入する。
SQL 文全体をリモート・サーバに転送 ( シッピング ) でき
な い とき は、プ ロ キシ・テ ー ブル に ロ ー を 挿入 す る。
RemoteScanOp も参照。
クエリ・プロセッサ
23
Lava クエリ実行エンジン
オペレータ
MergeJoinOp
説明
MergeUnionOp
2 つ以上のソート済み入力ストリームに対する union また
は union all 演算を実行する。入力ストリームの順序付けは、
出力ストリームでも必ず維持される。HashUnionOp と
UnionAllOp も参照。
NestedLoopJoinOp
2 つの入力ストリームのジョインを、ネストループ・ジョ
イン・アルゴリズムを使用して実行する。
NaryNestedLoopJoinOp
3 つ以上の入力ストリームのジョインを、拡張型ネスト
ループ・ジョイン・アルゴリズムを使用して実行する。こ
のオペレータは、NestedLoopJoin オペレータの左側の深
いツリーを置き換えるもので、入力ストリームの一部の
ローをスキップ可能である場合にパフォーマンスを大き
く向上させることができる。
OrScanOp
in または or の値をメモリ内テーブルに挿入し、値をソー
トして、重複を取り除く。この値を 1 つずつ返す。SQL
文に in 句や、同じカラムに対する複数の or 句がある場合
のみに使用される。
PtnScanOp
ローカル・テーブル ( 分割されているかどうかを問わず )
からローを読み取る。ローへのアクセスには、テーブル・
スキャンまたはインデックス・スキャンを使用する。
RIDJoinOp
左子オペレータから 1 つ以上のロー識別子 (RID) を受け
取り、右子オペレータ (PtnScanOp) を呼び出して対応す
るローを見つける。SQL 文に、同じテーブルの複数のカ
ラムに対する or 句がある場合のみに使用される。
RIFilterOp (Direct)
ロー単位で検査可能な参照整合性制約を適用するため
に、サブプランの実行を推進する。
ジョイン・カラムでソートされている 2 つのロー・スト
リームのジョインを、マージ・ジョイン・アルゴリズム
を使用して実行する。
参照整合性制約が設定されているテーブルに対する insert、
delete、または update のクエリのみで使用される。
RIFilterOp (Deferred)
クエリの影響を受けるローがすべて処理された後にのみ
検査可能な参照整合性制約を適用するために、サブプラ
ンの実行を推進する。
RemoteScanOp
プロキシ・テーブルにアクセスする。RemoteScanOp で
は、次のことが可能である。
RestrictOp
24
•
1 つのプロキシ・テーブルからローを読み取り、Lava
クエリ・プラン内の以降の処理をローカル・ホスト上
で行う。
•
SQL 文全体をリモート・ホストに渡して実行させる
(insert 文、delete 文、update 文、select 文 )。この場合、
Lava クエリ・プランは 1 つの EmitOp とその唯一の子オ
ペレータである RemoteScanOp から構成される。
•
任意の複雑さを持つクエリ・プラン・フラグメントを
リモート・ホストに渡して実行させ、結果のローを読
み取る ( 機能シッピング )。
式を評価する。
Adaptive Server Enterprise
第1章
オペレータ
SQFilterOp
Adaptive Server におけるクエリ処理 (QP) について
説明
1 つ以上のサブクエリを実行するために、サブプランの実
行を推進する。
ScalarAggOp
スカラ集合 (group by のない集合演算など ) を実行する。
SemiInsScrollOp
半反映型のスクロール可能カーソルをサポートするため
の、特別な処理を実行する。InsScrollOp も参照。
SequencerOp
クエリ・プラン内の複数のサブプランを強制的に逐次
モードで実行する。
SortOp
指定されたキーに基づいて入力ローをソートする。
SortOp (Distinct)
入力ローをソートして、重複を取り除く。
HashDisitnctOp と GroupSortedOp (Distinct) も参照。
StoreOp
ワークテーブルを作成してデータを挿入し、必要であれ
ばワークテーブルにクラスタード・インデックスを作成
する。子オペレータとして持つことができるのは 1 つの
InsertOp のみで、この InsertOp によってワークテーブル
にデータが挿入される。
UnionAllOp
2 つ以上の入力ストリームに対して union all 演算を実行
する。HashUnionOp と MergeUnionOp も参照。
UpdateOp
update 文全体をリモート・サーバに転送できない場合に、
ローカル・テーブルまたはプロキシ・テーブル内のロー
のカラムの値を変更する。RemoteScanOp も参照。
ExchangeOp
Lava クエリ・プランの並列実行を可能にし、並列実行の
調整を行う。ExchangeOp は、クエリ・プラン内のほぼ
どの Lava オペレータの間にも挿入することができ、これ
によってプランをいくつかのサブプランに分割して、そ
れぞれを並列実行することができる。詳細については、
「第 2 章 並列クエリ処理 (QP)」を参照。
Lava クエリの実行
Lava クエリ・プランの実行は、次の 5 つのフェーズで進行します。
1
Acquire - 実行に必要なリソースを獲得します。たとえば、メモリ・バッ
ファを獲得し、ワークテーブルを作成します。
2
Open - 結果ローを返すための準備を行います。
3
Next - 次の結果ローを生成します。
4
Close - クリーンアップを行います。たとえば、スキャンが完了したことを
アクセス層に通知したり、ワークテーブルをトランケートしたりします。
5
Release - Acquire で獲得したリソースを解放します。たとえば、メモリ・
バッファを解放し、ワークテーブルを削除します。
個々の Lava オペレータには、フェーズと同じ名前のメソッドがあり、対応す
るフェーズで呼び出されます。
クエリ・プロセッサ
25
Lava クエリ実行エンジン
図 1-2 のクエリ・プランを使用して、クエリ・プランの実行を説明します。
•
Acquire フェーズ
Emit オペレータの Acquire メソッドが呼び出されます。Emit オペレータ
は、自身の子である NestedLoopJoin オペレータの Acquire を呼び出しま
す。子オペレータは、自身の左子オペレータ (sysobjects の IndexScan) の
Acquire を呼び出し、次に、右子オペレータ (syscolumns の IndexScan) の
Acquire を呼び出します。
•
Open フェーズ
Emit オペレータの Open メソッドが呼び出されます。Emit オペレータは
NestedLoopJoin オペレータの Open を呼び出し、NestedLoopJoin オペ
レータは自身の左子オペレータの Open のみを呼び出します。
•
Next フェーズ
Emit オペレータの Next メソッドが呼び出されます。
Emit は NestedLoopJoin
オペレータの Next を呼び出し、NestedLoopJoin は自身の左子オペレータ
(sysobjects の IndexScan) の Next を呼び出します。IndexScan オペレータは、
sysobjects から最初のローを読み取り、NestedLoopJoin オペレータに返しま
す。NestedLoopJoin オペレータは、自身の右子オペレータ (syscolumns の
IndexScan) の Open メソッドを呼び出します。NestedLoopJoin オペレータ
は、syscolumns の IndexScan の Next メソッドを呼び出して、sysobjects からの
ローのジョイン・キーに一致するローを 1 つ取得します。一致するローが
見つかった場合は、Emit オペレータにそのローが返され、このオペレータ
によってクライアントに送信されます。Emit オペレータの Next メソッドが
繰り返し呼び出されて、さらに結果ローが生成されます。
•
Close フェーズ
すべてのローが返された後で、Emit オペレータの Close メソッドが呼び出さ
れます。これによって NestedLoopJoin オペレータの Close が呼び出され、さ
らにこのオペレータの両方の子オペレータの Close が呼び出されます。
•
Release フェーズ
Emit オペレータの Release メソッドが呼び出され、クエリ・プラン内の下
位のオペレータへ Release メソッドの呼び出しが波及していきます。
Release フェーズの実行が正常に終了すると、Lava クエリ・エンジンから手続
き型実行エンジンに制御が返されて、文の最終処理が行われます。
26
Adaptive Server Enterprise
第
2
章
並列クエリ処理 (QP)
この章では、並列クエリ処理 (QP) について詳しく説明します。
トピック名
垂直、水平、パイプライン並列処理
ページ
27
並列処理のメリットを利用できるクエリ
28
並列処理の有効化
29
セッション・レベルでの並列処理の制御
32
クエリの並列処理の制御
34
並列クエリの結果が異なる場合
34
並列クエリ・プランについて
36
Adaptive Server の並列クエリ実行モデル
38
垂直、水平、パイプライン並列処理
Adaptive Server では、クエリ実行に関して水平と垂直の並列処理がサポー
トされています。垂直並列処理とは、複数のオペレータを同時に実行でき
るということです。そのために、CPU やディスクなど、さまざまなシス
テム・リソースを必要とします。水平並列処理とは、1 つのオペレータの
複数のインスタンスを実行できるということです。インスタンスのそれぞ
れが、データの指定された一部分を処理します。
データをどのようにパーティション分割するかは、水平並列処理の動作に
大きな影響を及ぼします。データを論理的に分割することが有益であるの
は、大量のデータを処理する業務的意思決定システム (DSS) クエリの場合
です。Adaptive Server におけるデータ分割の詳細については、『システム
管理ガイド』を参照してください。この章の説明は、各種分割方式につい
て理解していることを前提としています。
クエリ・プロセッサ
27
並列処理のメリットを利用できるクエリ
Adaptive Server 15.0 では、パイプライン並列処理もサポートされます。パイプ
ライン並列処理とは、垂直並列処理の形態の 1 つで、中間結果がクエリ・ツ
リー内の上位のオペレータに渡されます。あるオペレータの出力が、別のオペ
レータの入力として使用されます。入力として使用されるオペレータと同時
に、データを供給するオペレータを実行できます。これが、パイプライン並列
処理に欠かせない要素です。並列処理を使用するのは、ディスクや CPU など
のリソースが複数利用可能な場合のみです。複数のリソースが連携できるよう
にシステムが構成されていない場合は、並列処理の使用が悪影響を及ぼすこと
があります。また、データを複数のディスク・リソースに分散させるときに、
データの論理分割方式が、並列デバイスでの物理分割と密接に結び付いている
必要があります。並列処理システムの最大の課題は、並列処理の粒度を正しく
制御することです。並列処理の粒度が細かすぎる場合は、並列処理によって得
られるメリットが、通信と同期化のオーバヘッドによって相殺されてしまうこ
とがあります。並列処理の粒度が粗すぎる場合は、スケーリングを適切に行う
ことができません。
並列処理のメリットを利用できるクエリ
並列クエリ処理を行うように Adaptive Server が設定されている場合は、クエ
リ・オプティマイザによって各クエリの評価が行われ、各クエリが並列処理に
適しているかどうかが判定されます。クエリが並列処理に適しており、並列ク
エリ・プランの方が逐次プランよりも高速になるとオプティマイザが判断した
場合は、クエリが複数のプラン・フラグメントに分割されて、これらのフラグ
メントが同時に処理されます。結果はまとめてクライアントに渡され、これに
要する時間は、そのクエリを 1 つのフラグメントとして逐次処理した場合より
も短くなります。
並列クエリ処理の実行によってパフォーマンスが向上するのは、次のような種
類のクエリです。
28
•
select 文によって非常に多くのページをスキャンするが、返されるローの
数が比較的少ない。たとえば、テーブル・スキャンまたはクラスタード・
インデックス・スキャンと、グループ化された集合演算またはグループ化
されていない集合演算の組み合わせの場合です。
•
テーブル・スキャンまたはクラスタード・インデックス・スキャンによっ
て非常に多くのページをスキャンするが、where 句によって返されるロー
の割合が非常に小さい。
•
select 文に union、order by、または distinct が含まれる。これらのクエリ
演算では、並列ソートや並列ハッシュ処理の利用が可能です。
•
select 文に対して再フォーマット方式がオプティマイザによって選択され
た場合。複数のワークテーブルにデータを挿入する処理を並列で実行で
き、並列ソートも利用できるからです。
Adaptive Server Enterprise
第2章
•
並列クエリ処理 (QP)
ジョイン・クエリも、並列アクセスのメリットを利用できます。
コマンドによって、大量かつ未ソートの結果セットが返される場合は、ネット
ワークの制約があるため、並列処理のメリットは期待できません。ほとんどの
場合は、結果をマージしてネットワーク経由でクライアントに返すよりも、
データベースから結果を返した方が速くなります。
insert、delete、update などの並列 DML はサポートされておらず、並列処理
によるメリットもありません。
並列処理の有効化
並列処理を行うように Adaptive Server を設定するには、パラメータ number of
worker processes と max parallel degree を有効化する必要があります。
最高のパフォーマンスを得るには、Adaptive Server によって生成されるプラン
の質に影響を与えるその他の設定パラメータについても知っておく必要があ
ります。
number of worker processes の設定
並列処理を有効化する前に、Adaptive Server が利用できるワーカー・プロセス
( スレッドと呼ぶこともあります ) の数を、number of worker processes を使用し
て設定する必要があります。十分な数のワーカー・プロセスを設定するように
してください。number of worker processes の値は、負荷ピーク時に必要となる
総数の 1.5 倍に設定することをおすすめします。max parallel degree 設定パラ
メータを使用して、おおよその数を計算することができます。このパラメータ
は、任意のクエリで使用できるワーカー・プロセスの総数を示します。Adaptive
Server への接続の数と、同時に実行されるクエリの数の概算値によって、一時
点で必要なワーカー・プロセスのおおよその数を求めるには、次のルールを使
用します。
number of worker processes の値 = [max parallel degree] × [ クエリを並列実行す
る同時接続数 ] × [1.5]
ワーカー・プロセスの数が不十分な場合は、クエリ・プロセッサが実行時にクエ
リ・プランの調整を試みます。最低限必要な数のワーカー・プロセスが利用不可
能な状態である場合は、クエリがアボートし、次のメッセージが返されます。
Insufficient number of worker processes to execute the parallel
query. Increase the value of the configuration parameter
'number of worker processes
ワーカー・プロセス数を 40 に設定するには、次のとおりに入力します。
sp_configure "number of worker processes", 40
クエリ・プロセッサ
29
並列処理の有効化
スレッド数に関する実行時調整が行われると、クエリのパフォーマンスが低下
する可能性があります。Adaptive Server はどのような場合もスレッドの使用の
最適化を試みますが、スレッドを調整しようとしたときに、より多くのリソー
スを必要とするプランに対してすでに確約してしまっている場合もあり、その
ため、スレッド数を減らして実行する場合の直線的スケールダウンが保証され
なくなります。
max parallel degree の設定
クエリ 1 つあたりの最大並列度を設定するには、max parallel degree 設定パラ
メータを使用します。このパラメータによって、Adaptive Server がクエリ 1 つ
を処理するために使用するスレッド数の最大値が決定します。最大並列度を
10 に設定するには、次のとおりに入力します。
sp_configure "max parallel degree", 10
以前のバージョンの Adaptive Server と異なり、クエリ・オプティマイザはこの
制限を完全には適用しません。完全に適用するためのプロセスは、最適化時間
と比較すると非常にコストの高い処理です。Adaptive Server は、ほぼ max
parallel degree の設定どおりに動作し、これを超えるのはセマンティック的な
理由による場合のみです。
max resource granularity の設定
max resource granularity の値は、1 つのクエリでシステム・リソースの何パーセ
ントまでを使用できるかを示します。現時点では、このオプションで考慮され
るのはプロシージャ・キャッシュのみです。デフォルトでは、10% に設定され
ます。ただし、このパラメータが実行時に適用されることはなく、クエリ・オ
プティマイザに対する参考データとしてのみ使用されます。max resource
granularity の値が低く設定されていれば、メモリを多用する方式、たとえば
ハッシュベースのアルゴリズムの使用をクエリ・エンジンが回避することがで
きます。
max resource granularity を 5% に設定するには、次のとおりに入力します。
sp_configure "max resource granularity", 5
30
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
max repartition degree の設定
Adaptive Server は、他のオペランドの分割方式に合わせるために、あるいは
パーティション排除を効率的に行うために、中間データの動的再分割を行う必
要があります。Adaptive Server による動的再分割の量を制御するには、設定パ
ラメータ max repartition degree を使用します。max repartition degree の値が大き
すぎる場合は、中間パーティションの数が増えすぎて、多数のワーカー・プロ
セスの間でリソースの競合が発生し、結局はパフォーマンスを低下させること
になります。max repartition degree の値によって、中間データ用に作成される
パーティションの最大数が決定します。再分割は、CPU を多用する操作です。
したがって、max repartition degree の値は、Adaptive Server エンジンの総数を超
えないように設定してください。
すべてのテーブルとインデックスが非分割である場合は、データの再分割の結
果として作成されるパーティションの数として max repartition degree の値が
使用されます。値が 1 ( デフォルト値 ) に設定されているときは、max repartition
degree の値はオンラインのエンジン数と等しくなるように設定されます。
max repartition degree は、force オプションを使用してテーブルまたはイン
デックスの並列スキャンを行うときにも使用されます。
select * from customers (parallel)
customers テーブルが分割されていないけれども force オプションが使用され
ている場合は、Adaptive Server はそのテーブルまたはインデックスの本来の分
割度を探します。この場合は 1 です。したがって、Adaptive Server は 2 つの事
項を基に分割度を決定します。1 つはサーバで設定されているエンジンの数
で、もう 1 つは、テーブルまたはインデックスのページ数に基づく最適な分割
度ですが、max repartition degree の値を超えることはありません。
max repartition degree を 5 に設定するには、次のとおりに入力します。
sp_configure "max repartition degree", 5
max scan parallel degree の設定
設定パラメータ max scan parallel degree は、下位互換性のみを目的として使用
されるもので、分割されたテーブルまたはインデックスのデータの偏りが大き
いときに使用されます。このパラメータの値が 1 より大きい場合は、この値を
使用してハッシュベース・スキャンが実行されます。max scan parallel degree の
値が max parallel degree の値を超えてはなりません。
クエリ・プロセッサ
31
セッション・レベルでの並列処理の制御
セッション・レベルでの並列処理の制御
set オプションを使用すると、並列度の制限をセッション単位で、またはスト
アド・プロシージャやトリガの中で設定することができます。これらのオプ
ションは、並列クエリでのチューニングの実験をするときに使用すると便利で
す。また、重要でないクエリを逐次モードで実行するようにこれらのオプショ
ンを使用して制限すれば、ワーカー・プロセスを他のタスクで使えるように残
しておくことができます。表 2-1 は、set オプションをまとめたものです。
表 2-1: セッション・レベルでの並列処理の制御
パラメータ
parallel_degree
機能
scan_parallel_degree
特定のセッション、ストアド・プロシージャ、またはトリ
ガの実行中のハッシュベース・スキャンに対して、ワー
カ ー・プ ロ セス の 最大 数 を設 定 する。max scan parallel
degree 設 定パ ラ メー タ より も 優先 さ れ るが、max scan
parallel degree の値以下でなければならない。
resource_granularity
グローバル値 max resource granularity よりも優先され、
セッション固有の値に設定される。この値は、メモリを多
用する操作を Adaptive Server が実行するかどうかに影響を
与える。
repartition_degree
セッションの max repartition degree の値を設定する。中間
データ・ストリームをセマンティック目的で再分割すると
きの最大分割度。
セッションのクエリ、ストアド・プロシージャ、またはト
リガに対して、ワーカー・プロセスの最大数を設定する。
max parallel degree 設定パラメータよりも優先されるが、
max parallel degree の値以下でなければならない。
set オプションに指定した値が大きすぎる場合は、対応する設定パラメータの
値が使用され、実際に使用された値がメッセージで報告されます。セッション
中、set parallel_degree、set scan_parallel_degree、set repartition_degree、ま
たは set resource_granularity が有効である間は、実行されるストアド・プロ
シージャのプランはプロシージャ・キャッシュ内に格納されません。これらの
オプションが有効である状態で実行されるプロシージャが生成するプランは、
最適なものではないことがあります。
32
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
set コマンドの例
次の例では、現在のセッションで開始されるすべてのクエリでワーカー・プロ
セスを 5 つに制限します。
set parallel_degree 5
このコマンドが有効な間は、分割数が 5 を超えるテーブルに対するクエリでは
パーティションベース・スキャンを使用できなくなります。
セッションの制限を削除するには、次のコマンドを使用します。
set parallel_degree 0
または
set scan_parallel_degree 0
それ以降のクエリを逐次モードで実行するときは、次のコマンドを使用します。
set parallel_degree 1
または
set scan_parallel_degree 1
リソース粒度を、システムの利用可能リソース全体の 25% に設定するには、次
のコマンドを使用します。
set resource_granularity 25
repartition_degree についても同様で、この値を 5 に設定できますが、max
parallel degree の値を超えてはなりません。
set repartition_degree 5
クエリ・プロセッサ
33
クエリの並列処理の制御
クエリの並列処理の制御
select コマンドの from 句に parallel 拡張機能を指定することにより、select 文で
使用されるワーカー・プロセスの数を指定できます。並列度には、sp_configure
で設定した値よりも大きい値や、set コマンドで制御されるセッションでの制
限値よりも大きい値を指定することはできません。大きい値を指定した場合、
その指定は無視され、set または sp_configure の制限値が使用されます。
select 文の構文は次のとおりです。
select ...
from tablename [( [index index_name]
[parallel [degree_of_parallelism | 1 ]]
[prefetch size] [lru|mru] ) ] ,
tablename [( [index index_name]
[parallel [degree_of_parallelism | 1]
[prefetch size] [lru|mru] ) ] ...
クエリ・レベルの parallel 句の例
1 つのクエリだけに対して並列度を指定するには、テーブル名の次に parallel
を指定します。次に示す例は、逐次で実行されます。
select * from huge_table (parallel 1)
次の例では、クエリで使用するインデックスを指定し、並列度を 2 に設定します。
select * from huge_table (index ncix parallel 2)
並列クエリの結果が異なる場合
クエリにスカラ集合操作が含まれていない場合や、最終ソート手順が必要ない
場合は、並列クエリで返される結果の順序が、同じクエリを逐次処理で実行し
たときとは異なることがあります。また、その後で同じクエリを並列で実行し
たときに、返される結果の順序が変化することがあります。ワーカー・プロセ
スが異なると速度も異なるため、結果セットの順序に違いが出ます。また、す
でにキャッシュに入っているページや、ロックの競合などによっても、それぞ
れの並列スキャンは違う動作になります。並列クエリで返される結果のセット
は常に同じで、異なるのは順序のみです。結果の順序が常に一定であるように
するには、order by を使用するか、クエリを逐次モードで実行します。
さらに、データ・ページを読み込む複数のワーカー・プロセスの速度調整の影
響があるため、次の 2 種類のクエリは、集合操作も最終ソートも実行されなけ
れば、同じデータにアクセスしても異なる結果を返すことがあります。
34
•
set rowcount を使用するクエリ
•
クエリ句によって十分にデータを絞り込むことなく、選択したカラムを
ローカル変数に格納するクエリ。
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
set rowcount を使用するクエリ
set rowcount オプションを指定すると、一定数のローがクライアントに返され
た後で処理が停止します。逐次処理では、プランが同じならば、実行を繰り返
しても結果は変わりません。逐次モードでは、プランが同じならば、特定の
rowcount 値に対して返されるローは毎回同じで、順序も変化しません。これ
は、1 つのプロセスだけでデータ・ページを毎回同じ順序で読み取るからです。
一方、並列クエリでは、ページへのアクセス速度がワーカー・プロセスごとに
異なる可能性があるため、返される結果の順序とローのセットが異なることが
あります。結果が常に同じであるようにするには、最終ソート手順を実行する
句を使用するか、クエリを逐次モードで実行してください。
ローカル変数を設定するクエリ
次のクエリは、select 文でローカル変数の値を設定します。
select @tid = title_id from titles
where type = "business"
where 句に一致する titles テーブルのローは複数あります。そのため、このロー
カル変数は常に、クエリによって返される一致するローのうち、最後のローの
値に設定されます。逐次処理の場合、値は常に同じになります。しかし、並列
クエリ処理の場合、結果は、ワーカー・プロセスの最後の状態により変わりま
す。一貫性のある結果を得るためには、最終ソート手順を実行する句を使用す
るか、クエリを逐次モードで実行してください。また、句を追加して、クエリ
引数に 1 つのローだけを選択させる方法もあります。
クエリ・プロセッサ
35
並列クエリ・プランについて
並列クエリ・プランについて
Adaptive Server 15.0 における並列クエリ処理を理解するうえで重要なことは、
並列クエリ処理がどのような基本ビルディング・ブロックで構成されているか
を知ることです (「第 3 章 showplan の使用」を参照 )。コンパイル済みクエリ・
プランは、実行オペレータのツリーで構成されていますが、これは、クエリの
関係セマンティクスによく似ています。クエリ・オペレータはそれぞれ、特定
のアルゴリズムを使用して関係演算を実装します。たとえば、nested loop join
というクエリ・オペレータは、関係ジョイン演算を実装します。Adaptive
Server15.0 における並列処理の主要オペレータは、xchg オペレータ (exchange
オペレータまたは交換オペレータともいいます ) です。これは制御オペレータ
であり、関係演算を実装するものではありません。xchg オペレータの目的は、
データ・フラグメントを処理できるワーカー・プロセスを新しく作成すること
です。最適化処理において、Adaptive Server によって適切な位置に xchg オペ
レータが配置され、これによって、並列で実行可能なオペレータ・ツリー・フ
ラグメントが作成されます。exchange オペレータ以下の、次の exchange オペ
レータが見つかるまでのすべてのオペレータがワーカー・スレッドによって実
行されます。ワーカー・スレッドは、オペレータ・ツリーのフラグメントを複
写して、データを並列で生成します。exchange オペレータは、このデータを、
クエリ・プラン内で自身の上位にある親オペレータに再配布します。exchange
オペレータは、データのパイプライン処理と再転送を扱います。
以下の項では、
「分割度」という言葉がさまざまな文脈で使用されます。テー
ブルまたはインデックスの分割度は、そのテーブルまたはインデックスのパー
ティション数を指します。演算または設定パラメータの分割度とは、中間デー
タ・ストリームにおいて生成されるパーティション数を表します。
次の例では、次に示すクエリが pubs2 データベースで実行されたときに、オ
ペレータがクエリ・プロセッサ内で逐次的に機能するようすを説明します。
テーブル titles は、カラム pub_id で 3 方向にハッシュ分割されています。
select * from titles
文 1 (1 行目 ) のクエリ・プラン。
1 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SCAN Operator
| FROM TABLE
| titles
| テーブル・スキャンです。
| 前方スキャン
| テーブルの最初に位置付けます。
| データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
| データ・ページに対する LRU でのバッファ置換方式
36
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
この例からわかるように、テーブル titles のスキャンが Scan オペレータによっ
て行われます。この詳細は、showplan の出力に表示されます。Emit オペレー
タは、データを Scan オペレータから読み取ってクライアント・アプリケー
ションに送信します。特定のクエリによって作成される、これらのオペレータ
から成る複合ツリーの複雑さは不定です。
この時点で、並列処理を有効化すると、scan オペレータの上位で xchg オペ
レータを使用することで、単純なスキャンを並列で実行できるようになりま
す。xchg によって、3 つのワーカー・プロセスが作成されます (3 つのパーティ
ションに基づく )。3 つに分けられたテーブルの各部分がこれらのワーカー・
プロセスによってスキャンされ、出力がコンシューマ・プロセスに送られま
す。ツリー最上位の Emit オペレータは、スキャンが並列で行われることを認
識しません。
例 A:
select * from titles
調整プロセスと 3 作業プロセスにより並列に実行されました。
4 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 3 Producer and 1 Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|RESTRICT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| titles
|
|
| テーブル・スキャンです。
|
|
| 前方スキャン
|
|
| テーブルの最初に位置付けます。
|
|
| 3 方向分割スキャンにより並列に実行されました。
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
|
|
| データ・ページに対する LRU でのバッファ置換方式
Exchange:Emit というオペレータが存在することに注目してください。このオ
ペレータは、Exchange オペレータの直下に置かれて、データを 1 つに集めま
す。Exchange オペレータの詳細については、
「exchange オペレータ」(38 ペー
ジ ) を参照してください。
クエリ・プロセッサ
37
Adaptive Server の並列クエリ実行モデル
Adaptive Server の並列クエリ実行モデル
並列クエリ実行モデルの主要コンポーネントの 1 つが、exchange オペレータで
す。このオペレータは、クエリの showplan の出力に表示されます。
exchange オペレータ
exchange オペレータによって、プロデューサ・オペレータとコンシューマ・オ
ペレータの間の境界が定められます。exchange オペレータの下位のオペレータ
がデータを生成 (produce) し、上位のオペレータがデータを消費 (consume) しま
す。例 A で示した titles テーブルの並列スキャンの例 (select * from titles) では、
exchange:emit オペレータと scan オペレータがデータを生成します。これにつ
いて、簡単に説明します。
select * from titles
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 3 Producer and 1
Consumer
processes.
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|RESTRICT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| titles
|
|
| テーブル・スキャンです。
この例では、1 つのコンシューマ・プロセスがパイプ ( プロセス境界を越えて
データを転送するための媒体 ) からデータを読み取り、emit オペレータに渡し
ます。このオペレータは、結果をクライアントに転送します。exchange オペ
レータは、ワーカー・プロセスの生成も行います。このワーカー・プロセス
を、producer スレッドと呼びます。exchange:emit オペレータは、exchange
によって管理されるパイプにデータを書き込むという処理も担当します。
38
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
図 2-1: クエリ・プラン内のプラン・フラグメントへのスレッドのバインド
図には、プロデューサとコンシューマ・タスクのプロセス境界も表示されてい
ます。このクエリ・プランには、2 つのプラン・フラグメントがあります。
Scan オペレータと EmitXchg オペレータを持つプラン・フラグメントが 3 つ
複製され、3 対 1 の Xchg オペレータによってパイプに書き込まれます。Emit
オペレータと Xchg オペレータは 1 つのプロセスによって実行されます。つま
り、このプラン・フラグメントの複製は 1 つだけです。
パイプ管理
exchange オペレータによって管理される 4 種類のパイプは、データ・ストリー
ムをどのように分割し、マージするかによって区別されます。exchange オペ
レータによって管理されるパイプがどのタイプであるかを知るには、showplan
の出力に表示されるパイプの説明を参照します。ここには、プロデューサとコ
ンシューマの数が表示されます。4 つのパイプのタイプについて、次に説明し
ます。
多対 1
この場合は、exchange オペレータによって複数のプロデューサ・スレッドが生
成され、これらのプロデューサ・スレッドが書き込んだパイプからデータを読
み取るコンシューマ・タスクが 1 つあります。前の例の exchange オペレータ
は、多対 1 の交換を実装します。多対 1 の exchange オペレータでは、順序付
けを維持することが可能です。このテクニックは特に、order by 句に対して並
列ソートを行い、結果のデータ・ストリームをマージして最終的なデータ順序
付けを生成する場合に使用されます。showplan の出力には、複数のプロデュー
サ・プロセスと 1 つのコンシューマ・プロセスが表示されます。
|EXCHANGE Operator
|Executed in parallel by 3 Producer and 1
Consumer processes
クエリ・プロセッサ
39
Adaptive Server の並列クエリ実行モデル
1 対多
多対多
この場合は、1 つのプロデューサと複数のコンシューマ・スレッドがあります。
プロデューサ・スレッドは、クエリ最適化のときに決定された分割方式に基づ
いて複数のパイプにデータを書き込みます。コンシューマ・スレッドはそれぞ
れ、割り当てられた 1 つのパイプからデータを読み取ります。この種のデータ
分割では、データの順序を維持できます。showplan の出力には、1 つのプロデュー
サ・プロセスと複数のコンシューマ・プロセスがあることが表示されます。
「多対多」とは、複数のプロデューサと複数のコンシューマがあることを意味
します。各プロデューサは複数のパイプに書き込み、各パイプには複数のコン
シューマがあります。各ストリームは 1 つのパイプに書き込まれます。コン
シューマ・スレッドはそれぞれ、割り当てられた 1 つのパイプからデータを読
み取ります。
|EXCHANGE Operator
|Executed in parallel by 3 Producer and 4
processes
exchange オペレータの
複写
Consumer
この場合は、exchange オペレータによって設定されたパイプのそれぞれに、プ
ロデューサ・スレッドのすべてのデータが書き込まれます。プロデューサ・ス
レッドは、ソース・データのコピーを作成します。コピー数はクエリ・オプ
ティマイザによって指定されますが、exchange オペレータのパイプの数に等し
くなります。コンシューマ・スレッドはそれぞれ、割り当てられた 1 つのパイ
プからデータを読み取ります。
ワーカー・プロセス・モデル
並列クエリ・プランは、さまざまなオペレータで構成されます。その中には、
最低 1 つの exchange オペレータがあります。実行時は、1 つの並列クエリ・プ
ランにいくつかのサーバ・プロセスのセットがバインドされ、これらのプロセ
スが並列でクエリ・プランを実行します。
ユーザ接続に結び付けられているサーバ・プロセスを「アルファ・プロセス」
と呼びます。このプロセスがソース・プロセスとなって、並列処理が実行され
るからです。特に、並列クエリ・プランの実行に関与する各ワーカー・プロセ
スは、アルファ・プロセスによって生成されます。
ワーカー・プロセスの生成に加えて、アルファ・プロセスはプラン実行に関与
するすべてのワーカー・プロセスの初期化も行います。また、ワーカー・プロ
セスがデータを交換するのに必要なパイプの作成と破棄も行います。アル
ファ・プロセスは、実質的に、1 つの並列クエリ・プランの実行を全体的に調
整する役割を持ちます。
実行時に、プラン内の個々の exchange オペレータにワーカー・プロセスの
セットが関連付けられます。ワーカー・プロセスは、exchange オペレータの
直下にあるクエリ・プラン・フラグメントを実行します。
「exchange オペレータ」(38 ページ ) に示した例 A のクエリでは、exchange オ
ペレータに 3 つのワーカー・プロセスが関連付けられています。この 3 つの
ワーカー・プロセスはそれぞれ、EmitXchg オペレータと Scan オペレータで
構成されるプラン・フラグメントを実行します。
40
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
図 2-2: 1 つの Xchg オペレータを持つクエリ実行プラン
個々の exchange オペレータには、
「ベータ・プロセス」と呼ばれるサーバ・
プロセスも関連付けられます。このプロセスは、アルファ・プロセスのことも
ワーカー・プロセスのこともあります。exchange オペレータに関連付けられ
たベータ・プロセスは、その exchange オペレータより下位のプラン・フラグ
メントの実行を調整する役割を持ちます。前述の例では、ベータ・プロセスは
アルファ・プロセスと同じプロセスです。実行されるプランには、exchange
オペレータの階層が 1 レベルしかないからです。
次に、このクエリを使用して、クエリ・プランに複数の exchange オペレータ
が存在する場合の動作を説明します。
select count(*),pub_id, pub_date
from titles
group by pub_id, pub_date
クエリ・プロセッサ
41
Adaptive Server の並列クエリ実行モデル
図 2-3: 2 つの exchange オペレータを持つクエリ実行プラン
図 2-3 には、Xchg-1 と Xchg-2 の 2 レベルの exchange オペレータがあります。
ワーカー・プロセス T4 は、exchange オペレータ Xchg-2 に関連付けられてい
るベータ・プロセスです。
ベータ・プロセスの役割は、exchange 以下のプラン・フラグメントの実行を
調整することです。ワーカー・プロセスに必要なクエリ・プラン情報を発信
し、複数のプラン・フラグメントの実行の同期をとります。
並列クエリ・プランの実行に関与するプロセスのうち、アルファ・プロセスで
もベータ・プロセスでもないものを、「ガンマ・プロセス」と呼びます。
実行時に、並列クエリ・プランは一意のアルファ・プロセスと 1 つ以上のベー
タ・プロセスおよび 1 つ以上のガンマ・プロセスにバインドされます。これ
は、ASE 15.0 の並列プランを並列で実行するには少なくとも 2 つの異なるプ
ロセスが必要 ( アルファとガンマ ) という規則に従っています。
exchange オペレータとワーカー・プロセスがどのようにマッピングされてい
るかと、どのプロセスがアルファ・プロセスでどのプロセスがベータ・プロセ
スであるかを調べるには、dbcc traceon(516) を使用します。
42
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
図 2-4: オペレータとプロセスとのマッピング
SQL 演算での並列処理の使用
テーブルやインデックスをパーティション分割するときは、アプリケーション
のニーズが最も良く反映されるような方法を選ぶことができます。I/O が十分
に並列化されるように、それぞれ異なる物理ディスクのセグメント上にパー
ティションを配置することをおすすめします。たとえば、テーブルの特定のカ
ラムに対するハッシングに基づいて分割する、あるいはパーティションに属す
る特定の範囲または値のリストに基づいて分割するなど、パーティションを明
確に定義することができます。ハッシュ方式、範囲方式、リスト方式の分割
は、「セマンティックベース」の分割に分類されます。このように呼ばれるの
は、特定のローがどのパーティションに属するかをあらかじめ決定できるから
です。
一方で、ラウンドロビン方式の分割には、対応するセマンティクスがありませ
ん。ローは任意のパーティションに存在することができます。分割するカラム
の選択と、使用する分割のタイプは、アプリケーションのパフォーマンスに大
きな影響を及ぼすことがあります。パーティションは、カーディナリティの低
いインデックスと考えられます。分割の定義の基準となるカラムは、アプリ
ケーション内のクエリに基づいているからです。
クエリ・プロセッサ
43
Adaptive Server の並列クエリ実行モデル
クエリ処理エンジンとそのオペレータは、Adaptive Server のパーティション分割
方式を利用しています。テーブルやインデックスに対して定義されている分割
を、静的分割と呼びます。さらに、Adaptive Server では、ジョイン、ベクトル集
合、distinct、union などの関係演算のニーズを満たすようにデータを動的に再分
割することも可能です。再分割はストリーミング・モードで行われ、記憶域へ
の格納は行われません。再分割は、alter table repartition コマンドとは異なるこ
とに注意してください。このコマンドでは、静的な再分割が行われます。
すでに説明したとおり、クエリ・プランは複数のクエリ実行オペレータで構成
されます。Adaptive Server 15.0 では、オペレータは次の 2 つに分類されます。
•
属性の影響を受けないオペレータ:scan、union all、scalar aggregation
など。これらのオペレータは、基盤となるパーティションには無関係です。
•
属性の影響を受けるオペレータ:join、distinct、union、vector aggregation
など。データに対する演算がいくつかの演算に分けられ、それぞれが少量
のデータ・フラグメントを処理します ( セマンティック・ベースのパー
ティション分割が使用されます )。その後で、単純な union all によって最
終的な結果セットが生成されます。この union all は、多対 1 の exchange
オペレータを使用して実装されます。
以下の項では、この 2 つのクラスのオペレータについて説明します。説明で使
用する例では、次に示すテーブルを使用します。このテーブルには、並列処理
が引き起こされるのに十分な量のデータが格納されているものとします。
create table RA2(a1 int, a2 int, a3 int)
属性の影響を受けない演算の並列処理
この項では、属性の影響を受けない演算について説明します。これに該当する
ものには、スキャン ( 逐次および並列 )、スカラ集合、union all などがあります。
テーブル・スキャン
水平並列処理を行うには、クエリ内の 1 つ以上のテーブルがパーティション分
割されているか、設定パラメータ max repartition degree が 1 より大きい値に設
定されている必要があります。max repartition degree が 1 の場合は、オンライ
ン・エンジンの数が参考情報として使用されます。Adaptive Server で水平並列
処理が実行されるときは、オペレータの複数のバージョンが並列で実行されま
す。複製されたオペレータは、それぞれのパーティションに対する操作を行い
ます。パーティションは、静的に作成されたもののことも、実行時に動的に構
築されたもののこともあります。
44
Adaptive Server Enterprise
第2章
逐次テーブル・スキャン
並列クエリ処理 (QP)
クエリの逐次実行の例を次に示します。この例では、テーブル RA2 のスキャン
を Table Scan オペレータを使用して行います。この演算の結果は Emit オペレー
タに転送され、このオペレータによって結果がクライアントに転送されます。
select * from RA2
文 1 (1 行目 ) のクエリ・プラン。
1 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SCAN Operator
| FROM TABLE
| RA2
| テーブル・スキャンです。
| 前方スキャン
| テーブルの最初に位置付けます。
| データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
| データ・ページに対する LRU でのバッファ置換方式
以前のリリースの Adaptive Server では、force オプションが使用される場合を
除いて、分割されていないテーブルに対してハッシュ・ベースのスキャンを使
用した並列スキャンが試行されることはありません。図 2-5 に、全ページ・
ロック・テーブルの逐次モードでのスキャンを 1 つのタスク T1 で実行するよ
うすを示します。このタスクは、テーブルのページ・チェーンをたどって各
ページを読み取り、必要なページがキャッシュ内にない場合は物理 I/O を実行
します。
図 2-5: 逐次タスクによるデータ・ページのスキャン
クエリ・プロセッサ
45
Adaptive Server の並列クエリ実行モデル
並列テーブル・スキャン
分割されていないテーブルに対して並列テーブル・スキャンを強制的に実行す
るには、以前のリリースと同様に、Adaptive Server の force オプションを使用
します。この場合は、ハッシュベースのスキャンが使用されます。
ハッシュベース・テーブ
ル・スキャン
図 2-6 に、ハッシュベース・テーブル・スキャンにおいて全ページロック・
テーブルからのデータ・ページにアクセスする作業を 3 つのワーカー・プロセ
スに分けるようすを示します。各ワーカー・プロセスは、すべてのページに対
して論理 I/O を実行しますが、各プロセスが検査するローは、図の網かけの部
分が示すようにページの 1/3 だけです。ハッシュベースのテーブル・スキャン
が使用されるのは、ユーザによって並列度が指定された場合のみです。詳細に
ついては、
「分割スキュー」(83 ページ ) を参照してください。
エンジンが 1 つの場合も、クエリ実行時に並列アクセスすることのメリットは
あります。ワーカー・プロセスが I/O を待機している間に他のワーカー・プロ
セスを実行できるからです。複数のエンジンがある場合は、いくつかのワー
カー・プロセスを同時に実行することができます。
図 2-6: 複数のワーカー・プロセスによる非分割テーブルのスキャン
ハッシュベースのスキャンでは、スキャンのための論理 I/O が増えます。各
ワーカー・プロセスがすべてのページにアクセスしてページ ID のハッシュを
計算するからです。データオンリー・ロック・テーブルの場合は、ハッシュ
ベース・スキャンによるハッシュ計算の対象はエクステント ID またはアロ
ケーション・ページ ID です。したがって、同じページを複数のワーカー・プ
ロセスがスキャンすることはなく、論理 I/O が増えることはありません。
パーティションベース・
テーブル・スキャン
46
このテーブルを次のように分割したとします。
alter table RA2 partition by range(a1, a2)
(p1 values <= (500,100), p2 values <= (1000, 2000))
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
同じクエリがもう一度実行されたときに、Adaptive Server はテーブルの並列ス
キャンを選択する可能性があります。並列スキャンが選択されるのは、スキャ
ンするページ数が多く、パーティション・サイズもほぼ均等であるために並列
処理によってクエリの効率が向上する場合のみです。
select * from RA2
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
3 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| RA2
|
|
| テーブル・スキャンです。
|
|
| 前方スキャン
|
|
| テーブルの最初に位置付けます。
|
|
| 2 方向分割スキャンにより並列に実行されました。
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用
しています。
|
|
| データ・ページに対する LRU でのバッファ置換方式
テ ー ブ ル の 分割後は、showplan の出力に 2 つのオペレータ exchange と
exchange:emit が追加されます。このクエリには 2 つのワーカー・プロセスが
含まれ、例 A で説明したとおり、それぞれが特定のパーティションをスキャ
ンして、データを exchange:emit オペレータに渡します。
図 2-7 に、3 つに分割されて 3 つの物理ディスク上に配置されているテーブル
をクエリがスキャンするようすを示します。エンジンが 1 つだけの場合も、こ
のクエリで並列処理を行うメリットはあります。ワーカー・プロセスが I/O や
他のプロセスによるロックの解放を待つためスリープしている間に他のワー
カー・プロセスを実行できるからです。複数のエンジンが使用可能ならば、複
数のワーカー・プロセスを複数のエンジン上で同時に実行することができま
す。このような構成では、パフォーマンスが非常に向上します。
クエリ・プロセッサ
47
Adaptive Server の並列クエリ実行モデル
図 2-7: 複数のワーカー・プロセスによる複数のパーティションへのアクセス
インデックス・スキャン
インデックスも、テーブルと同様に、分割することもしないことも可能です。
ローカル・インデックスは、テーブルの分割方式を継承します。ローカル・イ
ンデックス・パーティションはそれぞれ、1 つのパーティションのデータのみ
をスキャンします。グローバル・インデックスの分割方式はベース・テーブル
とは異なり、インデックスが 1 つまたは複数のパーティションを参照するよう
になっています。以下の項では、Adaptive Server でサポートされるインデック
ス構成について説明します。
グローバル・ノンクラス
タード・インデックス
Adaptive Server では、ノンクラスタードかつ非分割のグローバル・インデック
スは、すべてのテーブル分割方式に対してサポートされます。グローバル・イ
ンデックスは、以前のバージョンの Adaptive Server との互換性を保つためにサ
ポートされていますが、OLTP 環境においても役立ちます。インデックス・パー
ティションとデータ・パーティションは、同じ記憶域に配置することも、異な
る記憶域に配置することもできます。
ハッシュを使用したグ
ローバル・ノンクラス
タード・インデックスの
ノンカバード・スキャン
範囲によって分割されているテーブル RA2 に、分割されない、グローバルの
ノンクラスタード・インデックスを作成するには、次のとおりに入力します。
create index RA2_NC1 on RA2(a3)
次に示すクエリには、インデックス・キー a3 を使用する述部があります。
select * from RA2 where a3 > 300
文 1 (1 行目 ) のクエリ・プラン。
. . . . . . . . . . . . . .
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 3 Producer and 1
Consumer processes.
48
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|SCAN Operator
|
| FROM TABLE
|
| RA2
|
| インデックス:RA2_NC1
|
| 前方スキャン
|
|
| キーによって位置付けます。
|
|
| キー:
|
|
|
a3 ASC
|
|
| 3 方向ハッシュ・スキャンにより並列に実行されました。
|
|
| インデックス・リーフ・ページに対して I/O サイズ 2
キロバイトを使用しています。
|
|
| インデックス・リーフ・ページに対する
LRU でのバッファ置換方式
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを
使用しています。
| |
| データ・ページに対する LRU でのバッファ置換方式
この例で注目すべき点は、インデックス RA2_NC1 を使用するインデックス・
スキャンにおいて、exchange オペレータによって作成された 3 つのプロデュー
サ・スレッドが使用されることです。これらのプロデューサ・スレッドはそれ
ぞれ、条件を満たすリーフ・ページをすべてスキャンし、条件を満たすデータ
のロー ID に対するハッシュ・アルゴリズムを使用して、そのローが属するデー
タ・ページにアクセスします。この場合の並列処理は、データ・ページ・レベ
ルで行われます。
クエリ・プロセッサ
49
Adaptive Server の並列クエリ実行モデル
図 2-8: グローバル・ノンクラスタード・インデックスに対するハッシュベースの並
列スキャン
T1
T2
T3
図 2-9: 図 2-8 の凡例
このクエリで、データ・ページへのアクセスが必要ない場合は、並列では実行
されません。ただし、現在の方式では、パーティション分割カラムをクエリに
追加する必要があります。したがって、次の例に示すように、ノンカバード・
スキャンになります。
select a3 from RA2 where a3 > 300
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
50
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
3 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| RA2
|
|
| インデックス:RA2_NC1
|
|
| 前方スキャン
|
|
| キーによって位置付けます。
|
|
| キー:
|
|
|
a3 ASC
|
|
| 2 方向ハッシュ・スキャンにより並列に実行されました。
|
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロ
バイトを使用しています。
|
|
| インデックス・リーフ・ページに対する LRU でのバッファ置
換方式
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用し
ています。
|
|
| データ・ページに対する LRU でのバッファ置換方式
ノンクラスタード・グ
ローバル・インデックス
を使用するカバード・ス
キャン
ノンクラスタード・インデックスにパーティション分割カラムが含まれている
場合は、データ・ページにアクセスする理由がないので、クエリは逐次モード
で実行されます。このことを、次の例に示します。
create index RA2_NC2 on RA2(a3,a1,a2)
select a3 from RA2 where a3 > 300
文 1 (1 行目 ) のクエリ・プラン。
1 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|
|
|
クエリ・プロセッサ
|SCAN Operator
FROM TABLE
RA2
インデックス:RA2_NC2
| 前方スキャン
| キーによって位置付けます。
51
Adaptive Server の並列クエリ実行モデル
| インデックスは必要なカラムをすべて含んでいます。ベース・テーブル
は読み込まれません。
| キー:
|
a3 ASC
| インデックス・リーフ・ページに対して I/O サイズ 2 キロバイトを
使用しています。
| インデックス・リーフ・ページに対する LRU でのバッファ置換方式
クラスタード・インデッ
クス・スキャン
クラスタード・インデックスを持つ全ページ・ロック (APL) テーブルでは、
ハッシュベース・スキャン方式の使用は許可されません。許可される方式は、
パーティションベース・スキャンのみです。パーティションベース・スキャン
の使用が適切であると判断される場合に、この方式が使用されます。データオ
ンリー・ロック (DOL) テーブルの場合は、一般に、クラスタード・インデッ
クスは配置インデックスであり、ノンクラスタード・インデックスとして動作
します。したがって、APL テーブルのノンクラスタード・インデックスに関
する説明はすべて、DOL テーブルのクラスタード・インデックスにも当ては
まります。
ローカル・インデックス
Adaptive Server では、クラスタードとノンクラスタードのローカル・インデッ
クスがサポートされます。
分割されたテーブルの
クラスタード・イン
デックス
ローカルのクラスタード・インデックスがある場合は、複数のスレッドが各
データ・パーティションを並列でスキャンできるので、パフォーマンスが大幅
に向上する可能性があります。この並列処理のメリットを利用するには、分割
されたクラスタード・インデックスを使用します。これはローカル・インデッ
クスであるので、データは個々のパーティション内で別々にソートされます。
各データ・パーティションに関する情報は、パーティションの作成時に設定さ
れた境界値に準拠します。これにより、テーブル全体にわたってユニークなイ
ンデックス・キーを強制できます。
ユニークなクラスタード・ローカル・インデックスには、以下の制約があります。
分割されたテーブル
のノンクラスタード・
インデックス
52
•
インデックス・カラムには、すべての分割カラムが含まれている必要があ
ります。
•
分割カラムの順序付けは、インデックス定義の分割キーと同じでなければ
なりません。
•
複数のパーティションを持つラウンドロビン・テーブルに、ユニークなク
ラスタード・ローカル・インデックスを作成することはできません。
Adaptive Server では、分割されたテーブルに対するローカルのノンクラスター
ド・インデックスがサポートされます。
ただし、ローカル・インデックスを使うときはわずかな相違があります。ロー
カルのノンクラスタード・インデックスに対するカバード・インデックス・ス
キャンの実行時も、Adaptive Server は並列スキャンを使用することができま
す。これは、インデックス・ページも分割されているからです。
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
この相違を説明するために、次の例ではローカルのノンクラスタード・イン
デックスを作成します。
create index RA2_NC2L on RA2(a3,a1,a2) local index
select a3 from RA2 where a3 > 300
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
3 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| RA2
|
|
| インデックス:RA2_NC2L
|
|
| 前方スキャン
|
|
| キーによって位置付けます。
|
|
| インデックスは必要なカラムをすべて含んでいます。ベース・
テーブルは読み込まれません。
|
|
| キー:
|
|
|
a3 ASC
|
|
| 2 方向分割スキャンにより並列に実行されました。
|
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キ
ロバイトを使用しています。
|
|
| インデックス・リーフ・ページに対する LRU でのバッファ
置換方式
ローカル・インデックスに対するハッシュベース・スキャンが Adaptive Server
によって選択されることもあります。この方式が選択されるのは、別の並列度
が必要とされる場合や、パーティション内のデータに偏りがあるためにハッ
シュベースの並列スキャンのほうが望ましい場合です。
クエリ・プロセッサ
53
Adaptive Server の並列クエリ実行モデル
スカラ集合
T-SQL のスカラ集合演算は、逐次モードでも並列モードでも実行できます。
2 フェーズ・スカラ集合
並列スカラ集合では、集合演算が 2 フェーズに分けて実行され、2 つのスカラ
集合オペレータが使用されます。第 1 フェーズでは、下位のスカラ集合オペ
レータによってデータ・ストリームの集合演算が実行されます。第 1 フェーズ
のスカラ集合の結果は、多対 1 の exchange オペレータを使用してマージされ、
このストリームに対してもう一度集合演算が実行されます。
count(*) 集合演算の場合は、第 2 フェーズの集合演算でスカラ sum が実行さ
れます。これを表す showplan の出力を次の例に示します。
select count(*) from RA2
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
5 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SCALAR AGGREGATE Operator
| グループ化されていない SUM OR AVERAGE AGGREGATE を評価します。
|
|
|EXCHANGE Operator
|
|Executed in parallel by 2 Producer and 1 Consumer
processes.
54
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|SCALAR AGGREGATE Operator
| | グループ化されていない COUNT AGGREGATE を評価します。
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| RA2
|
|
| テーブル・スキャンです。
|
|
| 前方スキャン
|
|
| テーブルの最初に位置付けます。
|
|
| 2 方向分割スキャンにより並列に実行されました。
|
|
| データ・ページに対して I/O サイズ
2 キロバイトを使用しています。
|
|
| データ・ページに対する LRU でのバッファ置換方式
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
逐次集合
Adaptive Server は、集合演算を逐次モードで実行することを選択する場合があ
ります。集合演算の対象のデータが少なく、パフォーマンス面の利点が保証で
きない場合は、逐次集合方式が選択される可能性があります。逐次集合演算の
場合は、スキャンの結果が多対 1 の exchange オペレータを使用してマージさ
れます。このことを次の例に示します。この例では、非常に選択性の高い述部
が追加されているため、スカラ集合オペレータに流れ込むデータの量が非常に
少なくなります。このような場合は、集合演算を並列で実行しても、おそらく
は意味がありません。
select count(*) from RA2 where a2 = 10
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
4 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SCALAR AGGREGATE Operator
| グループ化されていない COUNT AGGREGATE を評価します。
|
|
|EXCHANGE Operator
|
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| RA2
|
|
|
| テーブル・スキャンです。
|
|
|
| 前方スキャン
|
|
|
| テーブルの最初に位置付けます。
|
|
|
| 2 方向分割スキャンにより並列に実行されました。
|
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使
用しています。
|
|
|
| データ・ページに対する LRU でのバッファ置換方式
クエリ・プロセッサ
55
Adaptive Server の並列クエリ実行モデル
Union all
Union All オペレータは、同じ名前の物理オペレータを使用して実装されます。
Union All は非常に単純な演算で、並列処理の効果が得られるのは大量のデー
タが通過する場合のみです。
並列 union all
並列 union all 生成の前提条件は、各オペランドの並列度が同一であるというこ
とだけで、分割のタイプは問いません。次に示す例では、union all オペレータ
が並列で処理されています。union all オペレータの上位に exchange オペレータ
があることから、このオペレータが複数のスレッドによって処理されることが
わかります。
次の例の説明のために、新しいテーブル HA2 が追加されています。
create table HA2(a1 int, a2 int, a3 int)
partition by hash(a1, a2) (p1, p2)
select * from RA2
union all
select * from HA2
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|UNION ALL Operator has 2 children.
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| RA2
|
|
|
| テーブル・スキャンです。
. . . . . . . . . . . . . . . . . . .
|
|
|
| 2 方向分割スキャンにより並列に実行されました。
. . . . . . . . . . . . . . . . . . .
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| HA2
56
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
|
|
|
| テーブル・スキャンです。
. . . . . . . . . . . . . . . . . . .
|
|
|
| 2 方向分割スキャンにより並列に実行されました。
逐次 union all
次の例では、union オペレータの両側からのデータは、それぞれの側の選択述
部を使用して絞り込まれています。そのため、union all オペレータに送り込ま
れるデータの量が少なくなるので、Adaptive Server は並列で実行しないことを
選んでいます。代わりに、テーブル RA2 と HA2 のスキャンはそれぞれ並列で
実行されます。そのために 2 対 1 の exchange オペレータが union の両側に追加
されています。その結果のオペランドが union all オペレータによって逐次モー
ドで処理されます。このことを次のクエリで示します。
select * from RA2
where a2 > 2400
union all
select * from HA2
where a3 in (10,20)
調整プロセスと 4 作業プロセスにより並列に実行されました。
7 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|UNION ALL Operator has 2 children.
|
|
|EXCHANGE Operator
|
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| RA2
|
|
|
| テーブル・スキャンです。
|
|
|
| 2 方向分割スキャンにより並列に実行されました。
|
|
|EXCHANGE Operator
|
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
クエリ・プロセッサ
|
|
|EXCHANGE:EMIT Operator
57
Adaptive Server の並列クエリ実行モデル
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|SCAN Operator
| FROM TABLE
| HA2
| テーブル・スキャンです。
| 2 方向分割スキャンにより並列に実行されました。
属性の影響を受ける演算の並列処理
この項では、属性の影響を受ける演算に関係する事項について説明します。こ
れに該当するものには、ジョイン、ベクトル集合、union などがあります。
ジョイン
2 つのテーブルのジョインを並列で行う場合、Adaptive Server はジョインの効
率向上のためにセマンティックベースのパーティション分割の使用を試みま
す。これは、ジョイン対象のデータの量と、各オペランドの分割のタイプに
よって決まります。ジョイン対象のデータの量が少ないけれども、各テーブル
のスキャン対象ページ数が非常に多い場合は、両側からの並列ストリームを直
列化してからジョインを逐次モードで実行します。この場合に、クエリ・オプ
ティマイザは、ジョイン演算を並列で実行することは次善の策であると判断し
ます。一般に、ジョイン・オペレータに使用されるオペランドの一方または両
方が中間オペレータ ( 別のジョインやグループ化オペレータ ) であってもかま
いませんが、ここで示す例では、スキャンのみがオペランドとして使用されて
います。
両テーブルが有用な分割
方式で分割されている
ジョインの各オペランドの分割が有用であるのは、ジョイン述部を考慮して分
割されている場合のみです。2 つのテーブルが同じ方式で分割されており、分
割カラムがジョイン述部のサブセットである場合は、これらのテーブルが等分
割されているといいます。たとえば、次の DDL コマンドを使用して、別のテー
ブル RB2 を作成するとします。このテーブルは RA2 と同様に分割されます。
create table RB2(b1 int, b2 int, b3 int)
partition by range(b1,b2)
(p1 values <= (500,100), p2 values <= (1000, 2000))
次に、RB2 を RA2 とジョインします。スキャンとジョインの並行処理は、新
たな再分割を行わなくても実行可能です。これが可能であるのは、RA2 の最
初のパーティションと RB2 の最初のパーティションをジョインし、次に RA2
の 2 番目のパーティションと RB2 の 2 番目のパーティションをジョインする
ことができるからです。これは「等分割ジョイン」と呼ばれ、次に示すように
2 つのテーブルをカラム a1、b1 と a2、b2 でジョインする場合にのみ実現し
ます。
select * from RA2, RB2
where a1 = b1 and a2 = b2 and a3 < 0
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
58
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
7 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|EXCHANGE:EMIT Operator
|
|
| | |NESTED LOOP JOIN Operator (Join Type: Inner Join)
|
|
|
|
|
|
|RESTRICT Operator
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
| FROM TABLE
|
|
|
|
| RB2
|
|
|
|
| テーブル・スキャンです。
|
|
|
|
| 前方スキャン
|
|
|
|
| テーブルの最初に位置付けます。
|
|
|
|
| 2 方向分割スキャンにより並列に実行されました。
|
|
|
|
|
|
|RESTRICT Operator
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
| FROM TABLE
|
|
|
|
| RA2
|
|
|
|
| テーブル・スキャンです。
|
|
|
|
| 前方スキャン
|
|
|
|
| テーブルの最初に位置付けます。
|
|
|
|
| 2 方向分割スキャンにより並列に実行されました。
exchange オペレータが、ネストループ・ジョインの上位にあります。つまり、
このオペレータによって 2 つのプロデューサ・スレッドが生成されます。最初
のスレッドは RA2 と RB2 の最初のパーティションをスキャンしてネストルー
プ・ジョインを実行し、2 番目のスレッドは RA2 と RB2 の 2 番目のパーティ
ションをスキャンしてネストループ・ジョインを実行します。この 2 つのス
レッドは、多対 1 の ( この場合は 2 対 1) exchange オペレータを使用して結果
をマージします。
一方のテーブルが有用
な分割方式で分割され
ている
この例では、alter table コマンドを使用し、テーブル RB2 をカラム b1 で 3 方向
ハッシュ分割に再分割しています。
alter table RB2 partition by hash(b1) (p1, p2, p3)
ここで、ジョイン・クエリを次のように変更してみます。
select * from RA2, RB2 where a1 = b1
クエリ・プロセッサ
59
Adaptive Server の並列クエリ実行モデル
テーブル RA2 の分割は有用ではありません。分割カラムがジョイン・カラム
のサブセットではないからです ( つまり、ジョイン・カラム a1 の値がそれぞ
れどのパーティションに属するかが不定 )。ただし、RB2 の分割は RB2 のジョ
イン・カラム b1 に一致するため、この分割は有用です。この場合は、クエリ・
オプティマイザによって、RB2 の分割と一致するようにテーブル RA2 がカラ
ム a1 ( ジョイン・カラム ) でハッシュ分割方式によって分割され、その後に、
3 方向マージ・ジョインが続きます。RA2 のスキャンの上位にある多対多 (2 対
3) の exchange オペレータによって、この動的再分割が行われます。merge join
オペレータの上位にある exchange オペレータによって、結果がマージされま
す。このオペレータは、多対 1 ( この例では 3 対 1) の exchange オペレータで
す。このクエリに対する showplan の出力を次に示します。
select * from RA2, RB2 where a1 = b1
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 5 作業プロセスにより並列に実行されました。
10 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 3 Producer and 1 Consumer
processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60
|EXCHANGE:EMIT Operator
|
|
|MERGE JOIN Operator (Join Type: Inner Join)
|
| ワーク・テーブル 3 を内部記憶に使用しています。
|
| Key Count: 1
|
| Key Ordering: ASC
|
|
|
|
|SORT Operator
|
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|Executed in parallel by 2 Producer
and 3 Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|RESTRICT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| RA2
|
|
| テーブル・スキャンです。
|
|
| 前方スキャン
Adaptive Server Enterprise
第2章
|
|
|
|
|
|
行されました。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
両テーブルの分割が有用
でない
|
|
|
|
|
|
|
|
|
|
並列クエリ処理 (QP)
テーブルの最初に位置付けます。
2 方向分割スキャンにより並列に実
|SORT Operator
| ワーク・テーブル 2 を内部記憶に使用しています。
|
|
|SCAN Operator
|
| FROM TABLE
|
| RB2
|
| テーブル・スキャンです。
|
| 前方スキャン
|
| テーブルの最初に位置付けます。
|
| 3 方向分割スキャンにより並列に実行されました。
次に示す例のジョインでは、両側のテーブルのネイティブの分割が有用ではあ
りません。テーブル RA2 はカラム (a1,a2) で分割され、RB2 はカラム (b1) で分
割されています。ジョイン述部ではまったく異なるカラム・セットが使用され
ており、両テーブルの分割はまったく役に立ちません。選択肢の 1 つとして、
ジョインの両側の動的再分割があります。これを行うには、M 対 N (2 対 3) の
exchange オペレータを使用してテーブル RA2 を再分割します。テーブル RA2
のカラム a3 がテーブル RB2 とのジョインに使用されているので、このカラム
が再分割用に選択されます。まったく同じ理由で、テーブル RB2 もカラム b3
で 3 方向に再分割されます。再分割後のジョインのオペランドは、ジョイン述
部に合わせて等分割されています。つまり、両側の対応するパーティションど
うしがジョインされます。一般に、ジョイン・オペレータの両側で再分割が必
要な場合は、Adaptive Server によってハッシュベースの分割方式が選択されま
す。前述の例では、テーブル RB2 と同様の範囲分割が使用されます。
select * from RA2, RB2 where a3 = b3
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 8 作業プロセスにより並列に実行されました。
12 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 3 Producer and 1 Consumer
processes.
|
|
|
|
|
|
|
クエリ・プロセッサ
|EXCHANGE:EMIT Operator
|
|
|MERGE JOIN Operator (Join Type: Inner Join)
|
| ワーク・テーブル 3 を内部記憶に使用しています。
|
| Key Count: 1
|
| Key Ordering: ASC
61
Adaptive Server の並列クエリ実行モデル
|
|
|
|
|
|
|SORT Operator
|
|
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|
|Executed in parallel by 2 Producer and 3
Consumer processes.
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|
|
|
|
|
|
|RESTRICT Operator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
|
|
|
| FROM TABLE
|
|
|
|
|
|
|
| RA2
|
|
|
|
|
|
|
| テーブル・スキャンです。
|
|
|
|
|
|
|
| 前方スキャン
|
|
|
|
|
|
|
| テーブルの最初に位置付けます。
|
|
|
|
|
|
|
| 2 方向分割スキャンにより並列に実
行されました。
|
|
|
|
|
|
|SORT Operator
|
|
|
| ワーク・テーブル 2 を内部記憶に使用しています。
|
|
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|
|Executed in parallel by 3 Producer and 3
Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
れました。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|SCAN Operator
|
| FROM TABLE
|
| RB2
|
| テーブル・スキャンです。
|
| 前方スキャン
|
| テーブルの最初に位置付けます。
|
| 3 方向分割スキャンにより並列に実行さ
一般に、ネストループ・ジョイン、マージ・ジョイン、ハッシュ・ジョインな
どのすべてのジョインは同じように動作します。ネストループ・ジョインには
1 つ例外があり、ネストループ・ジョインの内側では再分割が不可能です。こ
のような制約があるのは、ネストループ・ジョインでは、ジョイン述部のカラ
ムの値が外側から内側にプッシュされるからです。
62
Adaptive Server Enterprise
第2章
複写ジョイン
並列クエリ処理 (QP)
複写ジョインは、インデックス・ネストループ・ジョインを使用する必要があ
る場合に非常に役立ちます。サイズの大きいテーブルがあり、ジョイン・カラ
ムに非常に有用なインデックスが作成されているけれども、パーティション分
割は有用ではないとします。このテーブルを、サイズの小さな、分割されてい
ない ( または分割されている ) テーブルにジョインします。この場合は、小さ
い方のテーブルを N 回複写するという方法を利用できます。N は、大きい方
のテーブルのパーティションの数です。次に、大きい方のテーブルのパーティ
ションをそれぞれ小さい方のテーブルとジョインします。ジョインの内側に
exchange オペレータが必要ないので、インデックス・ネストループ・ジョイン
が使用可能です。このことを、次の例に示します。
create table big_table(b1 int, b2 int, b3 int)
partition by hash(b3) (p1, p2)
create index big_table_nc1 on big_table(b1)
create table small_table(s1 int, a2 int, s3 int)
select * from small_table, big_table
where small_table.s1 = big_table.b1
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 3 作業プロセスにより並列に実行されました。
7 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|NESTED LOOP JOIN Operator (Join Type: Inner Join)
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|Executed in parallel by 1 Producer and 2
Consumer processes.
|
|
|
|
|
|
|
|
クエリ・プロセッサ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|SCAN Operator
|
| FROM TABLE
|
| small_table
|
| テーブル・スキャンです。
63
Adaptive Server の並列クエリ実行モデル
|
|
|
|
|
|
|
|
|
並列再フォーマット
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|SCAN Operator
| FROM TABLE
| big_table
| インデックス:big_table_nc1
| 前方スキャン
| キーによって位置付けます。
| キー:
|
b1 ASC
| 2 方向ハッシュ・スキャンにより並列に実行されました。
これが特に役立つのは、ネストループ・ジョインを扱うときです。通常、再
フォーマットとは、ネスト・ジョインの内側を実体化してワークテーブルを作
成してからジョイン述部にインデックスを作成することを指します。並列クエ
リとネストループ・ジョインを使用するときに再フォーマットを行うのは、こ
れとは別の理由からです。ジョイン・カラムやネストループに対する有用なイ
ンデックスがまったくない場合は、サーバ/セッション/クエリ・レベルの設
定から、クエリの実行可能なオプションはジョインのみとなります。これは、
Adaptive Server にとって重要なオプションです。すでに説明したとおり、外側
には有用なパーティション分割が存在する可能性があり、分割がない場合も、
再分割によって有用な分割を生成することができます。一方、ネストループ・
ジョインの内側については、再分割とはテーブルを再フォーマットしてワーク
テーブルを作成し、新しい分割方式で分割することを意味します。このとき、
ネストループ・ジョインの内部スキャンでアクセスするのはワークテーブルと
なります。
次に示す例では、テーブル RA2 と RB2 の分割はそれぞれカラム (a1, a2) と
(b1, b2) で行われています。クエリの実行時は、セッション・レベルでマージ
とハッシュ・ジョインがオフに設定されます。
select * from RA2, RB2 where a1 = b1 and a2 = b3
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 12 作業プロセスにより並列に実行されました。
17 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SEQUENCER Operator has 2 children.
|
|
|EXCHANGE Operator
|
|Executed in parallel by 4 Producer and 1 Consumer
processes.
|
|
|
|
|
64
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|STORE Operator
|
| ワーク・テーブル 1 がロック・モード allpages で
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
REFORMATTING に対して作成されました。
|
|
|
| Creating clustered index.
|
|
|
|
|
|
|
|
|INSERT Operator
|
|
|
|
| 直接更新モードです。
|
|
|
|
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|
|
|Executed in parallel by 2 Producer and
4 Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|RESTRICT Operator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
|
|
|
|
| FROM TABLE
|
|
|
|
|
|
|
|
| RB2
|
|
|
|
|
|
|
|
| テーブル・スキャンです。
|
|
|
|
|
|
|
|
| 2 方向分割スキャンにより並
列に実行されました。
|
|
|
|
|
|
|
|
|
| TO TABLE
|
|
|
|
| Worktable1.
|
|
|EXCHANGE Operator
|
|Executed in parallel by 4 Producer and 1 Consumer
processes.
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|NESTED LOOP JOIN Operator (Join Type: Inner
Join)
|
|
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|
|Executed in parallel by 2 Producer and 4
Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
実行されました。
|
|
|
クエリ・プロセッサ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|SCAN Operator
|EXCHANGE:EMIT Operator
|
|
|RESTRICT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| RA2
|
|
| テーブル・スキャンです。
|
|
| 2 方向分割スキャンにより並列に
65
Adaptive Server の並列クエリ実行モデル
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FROM TABLE
Worktable1.
クラスタード・インデックスを使用します。
前方スキャン
キーによって位置付けます。
Sequencer というオペレータが存在することに注目してください。本質的に、
このオペレータは、自身の最後の子オペレータを除くすべての子オペレータを
実行し、その後で最後の子オペレータを実行します。この例では、最初の子オ
ペレータが実行されてテーブル RB2 が再フォーマットされ、ワークテーブル
が作成されます。このときに、カラム b1 と b3 での 4 方向ハッシュ分割が使
用されます。テーブル RA2 も、ワークテーブルの分割に一致するように 4 方
向に再分割されます。
逐次ジョイン
ジョインするデータの量によっては、ジョインを並列処理しても意味がないこ
とがあります。これまでの例で示したクエリに、テーブル RA2 と RB2 のそれ
ぞれに対する述部を追加した結果、ジョインされるデータが少なくなったとし
ます。このようなジョインは、逐次モードで実行される可能性があります。こ
のような場合は、これらのテーブルがどのように分割されているかは問題には
なりません。次の例に示すように、クエリが並列でテーブルをスキャンするこ
とによるメリットはあります。
select * from RA2, RB2 where a1=b1 and a2 = b2
and a3 = 0 and b2 = 20
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 4 作業プロセスにより並列に実行されました。
11 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|MERGE JOIN Operator (Join Type: Inner Join)
| ワーク・テーブル 3 を内部記憶に使用しています。
| Key Count: 1
| Key Ordering: ASC
|
|
|SORT Operator
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|EXCHANGE Operator
|
|
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|
66
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
|
|
|
|
|RESTRICT Operator
|
|
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
|
| FROM TABLE
|
|
|
|
|
| RA2
|
|
|
|
|
| テーブル・スキャンです。
| | | | | | 2 方向分割スキャンにより並列に実行されました。
|
|SORT Operator
|
| ワーク・テーブル 2 を内部記憶に使用しています。
|
|
|
|
|EXCHANGE Operator
|
|
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|RESTRICT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| RB2
|
|
| テーブル・スキャンです。
| | | 2 方向分割スキャンにより並列に実行されました。
セミジョイン
IN/EXIST サブクエリをフラット化した結果であるセミジョインの動作は、通
常の内部ジョインと同様です。ただし、セミジョインでは複写ジョインが使用
されません。このような状況では、1 つの外部ローが 2 回以上一致する可能性
があるからです。
外部ジョイン
外部ジョインの並列処理においては、複写ジョインは考慮されません。それ以
外の動作はすべて、通常の内部ジョインと同様です。もう 1 つの相違点は、外
部グループに属する外部ジョイン内のテーブルに対してはパーティション排
除が行われないことです。
ベクトル集合
ベクトル集合とは、group-by を持つクエリを指します。Adaptive Server がベク
トル集合を実行する方法には、さまざまなものがあります。実際のアルゴリズ
ムについては説明しませんが、並列処理での評価の手法のみを以下の項で説明
します。
分割済みベクトル集合
クエリ・プロセッサ
ベースまたは中間の関係においてグループ化が必要であり、分割カラムが
group by 句のカラムのサブセットまたはすべてのカラムと同じである場合は、
各パーティションに対するグループ化演算を並列で実行して、その結果のグ
ループ化されたストリームを単純な N 対 1 交換でマージすることが可能です。
これは、1 つのグループが複数のストリームに出現することはないからです。
グループ化カラムまたはそのサブセットでのセマンティックベースの分割を
使用するのであれば、このことはどの SQL クエリのグループ化に当てはまり
ます。この方式の並列ベクトル集合を、分割済み集合と呼びます。
67
Adaptive Server の並列クエリ実行モデル
次に示すクエリでは、並列分割済みベクトル集合が使用されます。カラム a1
と a2 での範囲分割が定義されており、これらのカラムが、集合演算を行うカ
ラムとも同じであるからです。
select count(*), a1, a2 from RA2 group by a1,a2
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
4 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|HASH VECTOR AGGREGATE Operator
|
|
| GROUP BY
|
|
| グループ化された COUNT AGGREGATE を評価します。
|
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| RA2
|
|
|
| テーブル・スキャンです。
|
|
|
| 前方スキャン
|
|
|
| テーブルの最初に位置付けます。
|
|
|
| 2 方向分割スキャンにより並列に実行されました。
|
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使
用しています。
|
|
|
| データ・ページに対する LRU でのバッファ置換方式
再分割ベクトル集合
場合によっては、テーブルまたは中間結果のパーティション分割がグループ化
演算に対して有用ではないことがあります。ただし、グループ化カラムに一致
するようにソース・データを再分割してから並列ベクトル集合を実行すれば、
グループ化演算を並列で実行することの価値はあります。このシナリオを次に
示します。分割を行うカラムは (a1, a2) ですが、このクエリではカラム a1 での
ベクトル集合を必要としています。
select count(*), a1 from RA2 group by a1
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 4 作業プロセスにより並列に実行されました。
6 operator(s) under root
68
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|HASH VECTOR AGGREGATE Operator
|
|
| GROUP BY
|
|
| グループ化された COUNT AGGREGATE を評価します。
|
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|Executed in parallel by 2 Producer and 2
Consumer processes.
|
|
|
|
|
|
|
|
|
|
2 フェーズ・ベクトル
集合
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|SCAN Operator
|
| FROM TABLE
|
| RA2
|
| テーブル・スキャンです。
|
| 前方スキャン
|
| テーブルの最初に位置付けます。
| | 2 方向分割スキャンにより並列に実行されました。
前の例で示したクエリでは、再分割のコストが高くなる可能性があります。こ
の他の方法としては、第 1 レベルのグループ化を実行してから N 対 1 の
exchange オペレータを使用してデータをマージし、その後で次のレベルのグ
ループ化を行うことが考えられます。この方法を「2 フェーズ・ベクトル集合」
と呼びます。グループ化カラムの重複の数に応じて、Adaptive Server は N 対 1
交換を通してデータ・ストリーミングのカーディナリティを減らすことを選択
する可能性があります。この場合は、第 2 レベルのグループ化のコストが比較
的低くなります。このことを、次の例に示します。
select count(*), a1 from RA2 group by a1
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
5 operator(s) under root
クエリのタイプは SELECT です。
クエリ・プロセッサ
69
Adaptive Server の並列クエリ実行モデル
ROOT:EMIT Operator
|HASH VECTOR AGGREGATE Operator
| GROUP BY
| グループ化された SUM OR AVERAGE AGGREGATE を評価します。
| ワーク・テーブル 2 を内部記憶に使用しています。
|
|
|EXCHANGE Operator
|
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|HASH VECTOR AGGREGATE Operator
|
|
|
| GROUP BY
|
|
|
| グループ化された COUNT AGGREGATE を評価します。
|
|
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
| FROM TABLE
|
|
|
|
| RA2
|
|
|
|
| テーブル・スキャンです。
|
|
|
|
| 2 方向分割スキャンにより並列に実行されました。
ベクトル集合 (vector aggregate) オペレータが 2 つあることに注目してくださ
い。ここから「2 フェーズ・ベクトル集合」という名称が付けられています。
逐次ベクトル集合
すでに示した例のいくつかと同様に、グループ化オペレータに流れ込むデータ
の量が述部の使用によって絞り込まれる場合は、並列で処理してもあまり意味
がないことがあります。このような場合は、パーティションのスキャンを並列
で実行し、N 対 1 の exchange オペレータを使用してストリームを直列化し、そ
の後で逐次ベクトル集合を実行します。このことを、次の例に示します。
select count(*), a1, a2 from RA2
where a1 between 100 and 200
group by a1, a2
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
4 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|HASH VECTOR AGGREGATE Operator
| GROUP BY
| グループ化された COUNT AGGREGATE を評価します。
| ワーク・テーブル 1 を内部記憶に使用しています。
|
70
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
|
|EXCHANGE Operator
|
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| RA2
|
|
|
| テーブルの最初に位置付けます。
|
|
|
| 2 方向分割スキャンにより並列に実行されました。
ここで重要なことは、分割カラムでのグループ化がいつでも可能とは限らない
ということです。また、グループ化カラムですでにテーブルが分割されていて
も、そのことを利用できるとは限りません。再分割を行ってグループ化を並列
で実行した方がよいか、あるいは分割されたテーブルでデータ・ストリームを
マージしてから逐次グループ化または 2 フェーズ集合を実行した方がよいか
の判断は、クエリ・オプティマイザが行います。
distinct
distinct 演算を持つクエリでは、グループ化ベクトル集合演算から集合演算の
部分を除いた処理が行われると考えるとよいでしょう。次に例を示します。
select distinct a1, a2 from RA2
これは、次のように書かれているのと同じです。
select a1, a2 from RA2 group by a1, a2
ベクトル集合に適用される方法論はすべて、この演算にも適用されます。
IN リストを持つクエリ
Adapative Server が IN リストを処理するときに使用される手法は、高度に最適
化されています。これは、よく使用される SQL 構成体です。したがって、
col in (value1, value2,..valuek)
これは、次のように書かれているのと同じです。
col = value1 OR col = value2 OR .... col = valuek
IN リスト内の値は特別なメモリ内テーブルに格納され、ソートされて重複が
取り除かれます。その後で、インデックス・ネストループ・ジョインを使用し
てベース・テーブルとジョインされます。次の例では、この動作が IN リスト
の 2 つの値と対応する OR リストの 2 つの値によって行われることが、次に示
す行に表れています。
SCAN Operator
FROM OR List
OR List has up to 2 rows of OR/IN values.
select * from RA2 where a3 in (1425, 2940)
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
6 operator(s) under root
クエリ・プロセッサ
71
Adaptive Server の並列クエリ実行モデル
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OR 句を持つクエリ
|EXCHANGE:EMIT Operator
|
|
|NESTED LOOP JOIN Operator (Join Type: Inner Join)
|
|
|
|
|SCAN Operator
|
|
| FROM OR List
|
|
| OR List has up to 2 rows of OR/IN values.
|
|
|
|
|RESTRICT Operator
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| RA2
|
|
|
| インデックス:RA2_NC1
|
|
|
| 前方スキャン
|
|
|
| キーによって位置付けます。
|
|
|
| キー:
|
|
|
|
a3 ASC
|
|
|
| 2 方向ハッシュ・スキャンにより並列に実行されました。
Adaptive Server は、OR 句などの論理和述部を扱うことができ、論理和の両側
を別々に適用してロー ID (RID) のセットを絞り込みます。重要な点は、両側
の論理和述部セットへのインデックスが作成可能でなければならないことで
す。また、論理和の両側の論理和述部の中にさらに論理和があってはなりませ
ん。つまり、論理和句や論理積句の深いネストを作ることは、ほとんど意味が
ないということです。次に示す例では、同じカラムに対する論理和述部があり
ますが ( 述部のカラムが異なっていてもかまいませんが、低コストでスキャン
できるようなインデックスが作成されている必要があります )、複数の述部に
よって絞り込まれるデータ・ローのセットがオーバラップすることもありま
す。Adaptive Server は、論理和の両側の述部を別々に使用してロー ID のセッ
トを絞り込みます。その後で、これらのロー ID の重複を取り除きます。
select a3 from RA2 where a3 = 2955 or a3 > 2990
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
8 operator(s) under root
クエリのタイプは SELECT です。
72
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer processes.
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|RID JOIN Operator
|
|
| ワーク・テーブル 2 を内部記憶に使用しています。
|
|
|
|
|
|
|HASH UNION Operator has 2 children.
|
|
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
| FROM TABLE
|
|
|
|
| RA2
|
|
|
|
| インデックス: RA2_NC1
|
|
|
|
| 前方スキャン
|
|
|
|
| キーによって位置付けます。
|
|
|
|
| インデックスは必要なカラムをすべて含んでいます。
ベース・テーブルは読み込まれません。
|
|
|
|
| キー:
|
|
|
|
|
a3 ASC
|
|
|
|
| 2 方向ハッシュ・スキャンにより並列に実行されました。
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
| FROM TABLE
|
|
|
|
| RA2
|
|
|
|
| インデックス: RA2_NC1
|
|
|
|
| 前方スキャン
|
|
|
|
| キーによって位置付けます。
|
|
|
|
| インデックスは必要なカラムをすべて含んでいます。
ベース・テーブルは読み込まれません。
|
|
|
|
| キー:
|
|
|
|
|
a3 ASC
|
|
|
|
| 2 方向ハッシュ・スキャンにより並列に実行されました。
|
|
|
|RESTRICT Operator
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
| FROM TABLE
|
|
|
|
| RA2
|
|
|
|
| 動的インデックスを使用します。
|
|
|
|
| 前方スキャン
|
|
|
|
| ロー識別子 (RID) によって位置付けます。
|
|
|
|
| データ・ページに対して I/O サイズ 2 キロバイト
を使用しています。
|
|
|
|
| データ・ページに対する LRU でのバッファ置換方式
クエリ・プロセッサ
73
Adaptive Server の並列クエリ実行モデル
この例でわかるように、インデックス RA2_NC1 を使用する 2 つのインデック
ス・スキャンが採用されています。このインデックスは、カラム a3 に定義さ
れています。次に、絞り込まれたロー ID のセットの中に重複するロー ID があ
るかどうかの検査が行われ、最後にベース・テーブルとのジョインが行われま
す。
「ロー識別子 (RID) によって位置付けます。」の行に注目してください。述
部の内容に応じて、論理和の両側で使用されるインデックスが異なっていても
かまいませんが、両方ともインデックス使用可能でなければなりません。この
ことを簡単に調べるには、論理和の片側だけを指定してクエリを実行して、そ
の述部がインデックス使用可能であることを確認します。Adaptive Server は、
インデックス交差のコストがテーブルの 1 回のスキャンよりも高コストであ
ると判断すると、インデックス交差を選択しないことがあります。
order by 句を持つクエリ
クエリに order by 句が存在するために出力をソートする必要がある場合に、
ソートを並列で実行することができます。初めに、元々存在する順序付けが利
用可能ならば、Adaptive Server はソートの実行を回避しようとします。ソート
を回避できない場合は、ソートを並列で実行できるかどうかを調べます。ソー
トを並列で実行するには、既存のデータ・ストリームを再分割するか、既存の
分割方式を使用して、分割されたストリームのそれぞれをソートします。結果
のデータを N 対 1 でマージし、exchange オペレータを維持します。
select * from RA2 order by a1, a2
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
4 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
74
|EXCHANGE:EMIT Operator
|
|
|SORT Operator
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| RA2
|
|
| インデックス: RA2_NC2L
|
|
| 前方スキャン
|
|
| インデックスの最初に位置付けます。
|
|
| 2 方向分割スキャンにより並列に実行されました。
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
ソートされるデータの量と利用可能なリソースに応じて、Adaptive Server は
データ・ストリームを再分割するときの分割度を現在のストリームの分割度よ
りも上げることがあります。このようにすることで、ソート演算の速度がさら
に向上します。このことが行われるのは、ソートを並列で実行することによる
メリットが、再分割によるオーバヘッドをはるかに上回る場合です。
サブクエリ
クエリにサブクエリが含まれている場合に、Adaptive Server は、さまざまな方
法を使用してサブクエリの処理コストを減らします。並列最適化をどのように
行うかは、サブクエリのタイプによって異なります。
•
実体化されたサブクエリ:実体化ステップに関しては、並列クエリ・メ
ソッドは検討されない。
•
フラット化されたサブクエリ:並列クエリ最適化が検討されるのは、サブ
クエリのフラット化の結果が通常の内部ジョインまたはセミジョインで
ある場合のみ。
•
ネストされたサブクエリ:並列処理が検討されるのは、サブクエリが含ま
れるクエリの最も外側にあるクエリ・ブロックに対してのみ。内部にある
ネストされたクエリは、常に逐次で実行される。つまり、ネストしたサブ
クエリ内のテーブルはすべて逐次モードでアクセスされます。次に示す例
では、テーブル RA2 へのアクセスは並列で行われますが、その結果は 2
対 1 の exchange オペレータを使用して直列化され、その後でサブクエリ
へのアクセスが行われます。サブクエリ内のテーブル RB2 へのアクセス
は、並列で行われます。
select count(*) from RA2 where not exists
(select * from RB2 where RA2.a1 = b1)
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
8 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SCALAR AGGREGATE Operator
| グループ化されていない COUNT AGGREGATE を評価します。
|
|
|SQFILTER Operator has 2 children.
|
|
|
|
|EXCHANGE Operator
|
|
|Executed in parallel by 2 Producer and 1 Consumer
processes.
クエリ・プロセッサ
75
Adaptive Server の並列クエリ実行モデル
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|RESTRICT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| RA2
|
|
| インデックス:RA2_NC2L
|
|
| 前方スキャン
|
|
| 2 方向分割スキャンにより並列に実行されました。
サブクエリ 1 の実行 ( ネスト・レベル 1)
サブクエリ 1 に対するクエリ・プラン ( ネスト・レベル 1、2 行目 )
相関サブクエリ。
EXISTS 述語内のサブクエリ。
|SCALAR AGGREGATE Operator
| グループ化されていない ANY AGGREGATE を評価します。
| 最初に該当するローまでだけをスキャンします。
|
|
|SCAN Operator
|
| FROM TABLE
|
| RB2
|
| テーブル・スキャンです。
|
| 前方スキャン
サブクエリ 1 に対するクエリ・プラン終了
次に示す例では、IN サブクエリがフラット化されてセミジョインになってい
ます。これは、実際には Adaptive Server によって内部ジョインに変換されるの
で、ジョイン順のテーブルを柔軟に入れ替えることができます。以下に示すよ
うに、当初サブクエリの中にあったテーブル RB2 には、並列でアクセスする
ようになっています。
select * from RA2 where a1 in (select b1 from RB2)
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 5 作業プロセスにより並列に実行されました。
10 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 3 Producer and 1 Consumer
76
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
processes.
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|MERGE JOIN Operator (Join Type: Inner Join)
|
|
| ワーク・テーブル 3 を内部記憶に使用しています。
|
|
| Key Count: 1
|
|
| Key Ordering: ASC
|
|
|
|
|
|
|SORT Operator
|
|
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
| FROM TABLE
|
|
|
|
| RB2
|
|
|
|
| テーブル・スキャンです。
|
|
|
|
| 3 方向分割スキャンにより並列に実行されました。
|
|
|
|
|
|
|SORT Operator
|
|
|
| ワーク・テーブル 2 を内部記憶に使用しています。
|
|
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|
|Executed in parallel by 2 Producer and 3
Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
行されました。
クエリ・プロセッサ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|RESTRICT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| RA2
|
|
| インデックス:RA2_NC2L
|
|
| 前方スキャン
|
|
| インデックスの最初に位置付けます。
|
|
| 2 方向分割スキャンにより並列に実
77
Adaptive Server の並列クエリ実行モデル
select into
クエリに select into 句がある場合は、クエリの結果セットを格納するための新
しいテーブルが作成されます。Adaptive Server が select into コマンドのベース・
クエリ部分を最適化する方法は、標準のクエリの最適化と同様ですが、並列ア
クセスと逐次アクセスの両方の方法が検討されます。並列で実行される select
into 文は、次のように処理されます。
•
select into 文で指定されたカラムを使用して、新しいテーブルを作成します。
•
新しいテーブルに N 個のパーティションを作成します。N は、このクエ
リ内の insert 操作に対してオプティマイザが選択した並列度です。
•
N 個のワーカー・プロセスを使用して、新しいテーブルにクエリの結果を
格納します。
•
最終的な分割が要求されていない場合は、新しいテーブルの分割を解除し
ます。
select into 文を並列実行するには、同等の逐次クエリ・プランを実行するとき
よりも多くのステップが必要です。次の例では、単純な select into を並列で実
行しています。
select * into RAT2 from RA2
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
4 operator(s) under root
クエリのタイプは INSERT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78
|EXCHANGE:EMIT Operator
|
|
|INSERT Operator
|
| 直接更新モードです。
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| RA2
|
|
| テーブル・スキャンです。
|
|
| 前方スキャン
|
|
| テーブルの最初に位置付けます。
|
|
| 2 方向分割スキャンにより並列に実行されました。
|
|
Adaptive Server Enterprise
第2章
|
|
|
|
|
|
います。
|
|
|
並列クエリ処理 (QP)
TO TABLE
RAT2
データ・ページに対して I/O サイズ 2 キロバイトを使用して
この例では、Adaptive Server はテーブル RA2 のスキャンからのストリームの
並列度を上げることはせず、このストリームを使用して出力先のテーブルへの
挿入を並列で行います。出力先テーブルは、初めは分割度 2 のラウンドロビン
分割を使用して作成されます。挿入が完了すると、テーブルの分割は解除され
ます。
挿入されるデータ・セットのサイズがそれほど大きくない場合は、Adaptive
Server がデータの挿入を逐次で行うことを選択する場合もあります。この場合
も、ソース・テーブルのスキャンは並列で行うことができます。出力先テーブ
ルは、非分割テーブルとして作成されます。
Adaptive Server 15.0 では、select into 句で最終的な分割方式を指定できるよう
に機能が拡張されています。この場合、出力先テーブルはその分割方式を使用
して作成され、データの挿入は最も効率的な方法を使用して行われます。ソー
ス・データと同様に出力先テーブルを分割する必要があり、挿入されるデータ
の量が十分多い場合は、挿入演算が並列で実行されます。
次の例では、ソース・テーブルと出力先テーブルの両方で同じ分割方式が使用
されています。Adaptive Server はこのシナリオを認識し、ソース・データを再
分割しないことを選択しています。
select * into new_table
partition by range(a1, a2)
(p1 values <= (500,100), p2 values <= (1000, 2000))
from RA2
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
4 operator(s) under root
クエリのタイプは INSERT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer
processes.
|
|
|
|
|
|
|
クエリ・プロセッサ
|EXCHANGE:EMIT Operator
|
|
|INSERT Operator
|
| 直接更新モードです。
|
|
|
|
|SCAN Operator
79
Adaptive Server の並列クエリ実行モデル
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ています。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FROM TABLE
RA2
テーブル・スキャンです。
前方スキャン
テーブルの最初に位置付けます。
2 方向分割スキャンにより並列に実行されました。
TO TABLE
RRA2
データ・ページに対して I/O サイズ 16 キロバイトを使用し
ソース・テーブルの分割方式が出力先テーブルのものと一致しない場合は、
ソース・データを再分割する必要があります。このことを次の例に示します。
この例では、挿入は 2 つのワーカー・プロセスを使用して並列で行われます。
その前に、データが 2 対 2 の exchange オペレータを使用して再分割されてお
り、これによってデータが範囲分割からハッシュ分割に変換されています。
select * into HHA2
partition by hash(a1, a2)
(p1, p2)
from RA2
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 4 作業プロセスにより並列に実行されました。
6 operator(s) under root
クエリのタイプは INSERT です。
ROOT:EMIT Operator
|EXCHANGE Operator
|Executed in parallel by 2 Producer and 1 Consumer processes.
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|INSERT Operator
|
|
| 直接更新モードです。
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|Executed in parallel by 2 Producer and 2 Consumer
processes.
|
|
|
|
|
80
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|SCAN Operator
|
| FROM TABLE
Adaptive Server Enterprise
第2章
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ます。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
並列クエリ処理 (QP)
RA2
テーブル・スキャンです。
前方スキャン
テーブルの最初に位置付けます。
2 方向分割スキャンにより並列に実行されました。
TO TABLE
HHA2
データ・ページに対して I/O サイズ 16 キロバイトを使用してい
insert/delete/update
insert、delete、update のオペレーションは、Adaptive Server 15.0 では逐次モー
ドで行われます。ただし、クエリ内の出力先テーブル以外のテーブルのうち、
削除または更新対象のローを絞り込むために使用するテーブルには、並列でア
クセスすることができます。
delete from RA2
where exists
(select * from RB2
where RA2.a1 = b1 and RA2.a2 = b2)
文 1 (1 行目 ) のクエリ・プラン。
調整プロセスと 3 作業プロセスにより並列に実行されました。
9 operator(s) under root
クエリのタイプは DELETE です。
ROOT:EMIT Operator
|DELETE Operator
| 遅延更新モードです。
|
|
|NESTED LOOP JOIN Operator (Join Type: Inner Join)
|
|
|
|
|SORT Operator
|
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|Executed in parallel by 3 Producer and 1 Consumer
processes.
|
|
|
|
|
|
クエリ・プロセッサ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|RESTRICT Operator
|
|
|
|
|SCAN Operator
81
Adaptive Server の並列クエリ実行モデル
|
|
|
|
|
|
| FROM TABLE
|
|
|
|
|
|
| RB2
|
|
|
|
|
|
| テーブル・スキャンです。
|
|
|
|
|
|
| 前方スキャン
|
|
|
|
|
|
| テーブルの最初に位置付けます。
| | | | | | | 3 方向分割スキャンにより並列に実行されました。
|
|
|
|
|
|
| データ・ページに対して I/O サイズ 2 キロ
バイトを使用しています。
|
|
|
|
|
|
| データ・ページに対する LRU でのバッファ置
換方式
|
|
|
|
|RESTRICT Operator
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| RA2
|
|
|
| インデックス: RA2_NC1
|
|
|
| 前方スキャン
|
|
|
| キーによって位置付けます。
|
|
|
| キー:
|
|
|
|
a3 ASC
|
| TO TABLE
| RA2
| データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
この例からわかるように、削除対象のテーブル RB2 に対するスキャンと削除
は逐次で行われます。ただし、テーブル RA2 のスキャンは並列で行われてい
ます。update 文や insert 文についても同じシナリオが当てはまります。
パーティション排除
セマンティック分割の利点は、クエリ・プロセッサがこの分割方式のメリット
を利用できることと、コンパイル時に不要なパーティションを排除できること
です。これは、範囲、ハッシュ、リストの分割方式の場合に可能です。ハッ
シュ・パーティションでは、パーティションを排除するために使用できるのは
等号述語のみです。範囲パーティションやリスト・パーティションでは、等号
述語と不等号述語を使用できます。たとえば、テーブル RA2 のセマンティッ
ク分割がカラム a1, a2 で (p1 values <= (500,100) and p2 values <= (1000, 2000)) と
定義されているとします。カラム a1 またはカラム a1, a2 に対する述部がある
場合は、パーティション排除が可能です。次に例を示します。
select * from RA2 where a1 > 1500
上記の文を満たすデータはありません。このことは、showplan の出力でわかり
ます。
文 1 (1 行目 ) のクエリ・プラン。
................................
|
|
|SCAN Operator
82
Adaptive Server Enterprise
第2章
|
|
|
|
|
|
|
|
|
|
|
|
並列クエリ処理 (QP)
FROM TABLE
RA2
[ Eliminated Partitions : 1 2 ]
インデックス: RA2_NC2L
「Eliminated Partitions」という語句のところに表示されるのは、パーティション
がどのように作成されたかに従って割り当てられた識別用の順序番号です。
テーブル RA2 については、p1 where (a1, a2) <= (500, 100) で表されるパーティ
ションがパーティション番号 1 で、p2 where (a1, a2) > (500, 100) and <= (1000,
2000) がパーティション番号 2 であると見なされます。
例として、ハッシュ分割されたテーブルに対する等号クエリを考えてみます。
この例では、ハッシュ分割のすべてのキーに等号句があります。このことを示
すために、テーブル HA2 を使います。このテーブルは、カラム (a1, a2) で 2
方向ハッシュ分割されています。順序番号とは、パーティションが sp_help の
出力に表示されるときの順序を指します。
select * from HA2 where a1 = 10 and a2 = 20
文 1 (1 行目 ) のクエリ・プラン。
................................
|SCAN Operator
| FROM TABLE
| HA2
| [ Eliminated Partitions : 1 ]
| テーブル・スキャンです。
分割スキュー
分割スキューは、並列パーティション・スキャンを採用できるかどうかの判断
において非常に重要な役割を持ちます。Adaptive Server では、分割スキューは
平均パーティション・サイズに対する最大パーティション・サイズの比率とし
て定義されます。たとえば、あるテーブルに 4 つのパーティションがあり、サ
イズはそれぞれ 10 ページ、20 ページ、35 ページ、80 ページであるとします。
この場合、平均パーティション・サイズは (20 + 20 + 35 + 85)/4 = 40 ページで
す。最大のパーティションのサイズは 85 ページであるので、分割スキューの
計算は 85/40 = 2.125 となります。パーティション・スキャンの場合、並列ス
キャンを実行するコストは、最大パーティションのスキャンのコストにほぼ等
しくなります。代わりに、ハッシュベースのパーティションではかなり高速に
なります。個々のワーカー・プロセスがページ番号またはアロケーション・ユ
ニットに対するハッシュを実行して、データの一部をスキャンするからです。
分割スキューによるパフォーマンス低下というデメリットは、常にスキャン・
レベルで現れるとは限らず、データに対するいくつものジョイン・オペレータ
のような、複雑なオペレータとして現れることがあります。このような場合
は、誤差範囲が急激に増大します。
分割スキューは、テーブルに対して sp_help を実行することによって簡単に見
つかります。
クエリ・プロセッサ
83
Adaptive Server の並列クエリ実行モデル
sp_help HA2
........
name
type partition_type partitions partition_keys
------ -------------------- -------------- ----------HA2
base table
hash
2 a1, a2
partition_name partition_id pages
segment
create_date
-------------------------- ------------ ----------- -------------------------------------HA2_752002679
752002679
324 default
Aug 10 2005 2:05PM
HA2_768002736
768002736
343 default
Aug 10 2005 2:05PM
Partition_Conditions
-------------------NULL
Avg_pages
Max_pages
Min_pages
Ratio(Max/Avg)
Ratio(Min/Avg)
----------- ----------- ----------- ---------------------------------------------------333
343
324
1.030030
0.972973
または、systabstats システム・カタログの問い合わせを実行してスキューを
計算することもできます。問い合わせの結果として、各パーティションのペー
ジ数が表示されます。
84
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
クエリが並列で実行されない場合
Adaptive Server がクエリを逐次モードで実行するのは、次の場合です。
•
データ量が少ないので、並列アクセスのメリットが得られない。
•
次のように、クエリに等価ジョイン述部がない。
select * from RA2, RB2
where a1 > b1
•
スレッドやメモリなどのリソースが十分ではないので、クエリを並列で実
行できない。
•
グローバル・ノンクラスタード・インデックスのカバード・スキャンが使
用されている。
•
テーブルやインデックスへのアクセスが、ネストしたサブクエリの内側に
あるが、サブクエリをフラット化できない。
実行時調整
実行時に使用可能なワーカー・プロセスの数が不十分な場合は、プラン内に存
在する exchange オペレータで使用されるワーカー・プロセスの数を減らせる
かどうかを、実行エンジンが試行します。
これは、2 とおりの方法で行われます。
•
まず、クエリ・プラン内の特定の exchange オペレータが使用するワーカー・
プロセス数を、クエリの逐次再コンパイルを行うことなく減らすことを試
みます。クエリ・プランのセマンティクスに応じて、一部の exchange オペ
レータは調整可能ですが、それ以外は調整不可能です。オペレータによっ
ては、調整できる方法が限られているものがあります。
•
並列クエリ・プランを実行するには、最低でもいくつかのワーカー・プロ
セスが必要です。必要な数のワーカー・プロセスが使用可能でない場合
は、クエリが逐次モードに再コンパイルされます。再コンパイルが不可能
な場合は、クエリがアボートされ、エラー・メッセージが生成されます。
Adaptive Server 15.0 では、次のタイプのクエリに対する逐次再コンパイルがサ
ポートされます。
•
すべてのアドホック select クエリ (select into、alter table、execute immediate
のクエリを除く )
•
すべてのストアド・プロシージャ (select into および alter table のクエリを
除く )
アドホックおよびストアド・プロシージャでの select into のサポートは、今後
のリリースで追加される予定です。
クエリ・プロセッサ
85
Adaptive Server の並列クエリ実行モデル
実行時調整の識別と管理
Adaptive Server は、クエリ・プランの実行時調整の監視に役立つ、次の 2 つの
メカニズムを備えています。
•
set process_limit_action により、実行時調整が行われる場合または警告が
出力される場合に、バッチ処理やプロシージャをアボートできる。
•
実行時調整が行われたときに、showplan が有効ならば、調整されたクエ
リ・プランが showplan によって出力される。
set process_limit_action の使用
set コマンドの process_limit_action オプションを使用すると、調整されたクエ
リ・プランの使用をセッション・レベルまたはストアド・プロシージャ・レベ
ルで監視できます。process_limit_action を "abort" に設定すると、調整されたク
エリ・プランが必要となった場合にエラー 11015 が記録され、クエリがアボー
トします。process_limit_action を "warning" に設定すると、エラー 11014 が記録
されますが、クエリは実行されます。たとえば、次のコマンドは、クエリが実
行時に調整される場合にバッチ処理をアボートします。
set process_limit_action abort
エラー・ログに記録されているエラー 11014 とエラー 11015 を調べると、最適
化されたクエリ・プランの代わりに調整されたクエリ・プランがどの程度使用
されたかを確認できます。制限を解除して実行時調整を可能にするには、次の
コマンドを使用します。
set process_limit_action quiet
process_limit_action の詳細については、
『ASE リファレンス・マニュアル』の
set の項を参照してください。
showplan の使用
showplan を使用すると、クエリの実行の前に、そのクエリに対する最適化され
たプランが表示されます。クエリ・プランに並列処理が含まれ、実行時調整が
行われる場合は、showplan は次のメッセージに続けて調整クエリ・プランを表
示します。
AN ADJUSTED QUERY PLAN IS BEING USED FOR STATEMENT 1 BECAUSE
NOT ENOUGH WORKER PROCESSES ARE CURRENTLY AVAILABLE.
ADJUSTED QUERY PLAN:
set noexec が有効であるときは、クエリは実行されません。したがって、この
オプションを使用するときは実行時プランが表示されません。
86
Adaptive Server Enterprise
第2章
並列クエリ処理 (QP)
実行時調整の発生回数の削減
実行時調整の数を減らすには、並列クエリに使用できるワーカー・プロセス数
を増やしてください。これは、より多くの合計ワーカー・プロセス数をシステ
ムに追加するか、重要でないクエリに対する並列処理の実行を制限または削除
することで可能になります。次のいずれかの方法を使います。
•
set parallel_degree を使用して、セッション・レベルで並列度の上限を設
定する。
•
クエリ・レベルの parallel 1 句と parallel N 句を使用して、個々の文での
ワーカー・プロセスの使用を制限する。
システム・プロシージャについて実行時調整の数を減らす場合は、サーバ・レ
ベルまたはセッション・レベルの並列度を変更してから、プロシージャを再コ
ンパイルします。詳細については、
『ASE リファレンス・マニュアル』の
sp_recompile の項を参照してください。
クエリ・プロセッサ
87
Adaptive Server の並列クエリ実行モデル
88
Adaptive Server Enterprise
第
3
章
showplan の使用
この章では、showplan ユーティリティによって出力されるメッセージにつ
いて説明します。showplan は、バッチまたはストアド・プロシージャ内の
各 SQL 文について、テキストベースのフォーマットでクエリ・プランを
表示します。
トピック名
クエリ・プランの表示
ページ
89
文レベル出力
91
Lava クエリ・プランの形状
94
和集合オペレータ
131
クエリ・プランの表示
クエリ・プランを表示するには、次のコマンドを使用します。
set showplan on
クエリ・プランの表示を停止するには、次のコマンドを使用します。
set showplan off
showplan は他の set コマンドと併用できます。
ストアド・プロシージャの showplan を実行しないで表示する場合は、set
fmtonly コマンドを使用します。
双方のオペレーションにオプションがどのように影響するかについては、
『パフォーマンス&チューニング・ガイド:オプティマイザと抽象プラン』
の「第 32 章 クエリ・チューニング用ツール」を参照してください。
注意 set noexec をストアド・プロシージャに使用しないでください。コ
ンパイルと実行が行われず、必要な出力が得られません。
クエリ・プロセッサ
89
クエリ・プランの表示
ASE 15.0 でのクエリ・プラン
Adaptive Server 15.0 には、次のように 2 種類のクエリ・プランがあります。
•
ASE 15.0 よりも前の従来のクエリ・プランは、set や create table など、
Lava クエリ・エンジンでは実行されない SQL 文に対して引き続き使用さ
れます。
•
新しいオプティマイザによって選択されたクエリ・プランは、Lava クエ
リ実行エンジンによって実行されます。
従来のクエリ・プランは Adaptive Server 15.0 では変更されておらず、その
showplan 出力も変更されていません。次の showplan 出力は、従来のクエリ・
プランの例です。
1> set showplan off
2> go
文 1 (1 行目 ) のクエリ・プラン。
STEP 1
クエリのタイプは SET OPTION OFF です。
Lava クエリ・エンジンで実行されるクエリ・プランは、以前のバージョンの
クエリ・エンジンで実行されてきたクエリ・プランとはかなり違います。した
がって、対応する showplan の出力も大幅に変更されています。showplan が表
示する Lava クエリ・プランの新しい機能には、次のものがあります。
•
プラン要素 - Lava クエリ・プランは、30 以上のさまざまな Lava オペレー
タから構成できます。
•
プラン形状 - Lava クエリ・プランは、Lava オペレータを逆向きにしたツ
リー構造です。一般的に、クエリ・プランにより多くのオペレータが存在
すると、可能なツリー形状の組み合わせが増えることになります。
•
並列実行されるサブプラン。
これ以降では、Lava クエリ・プランの showplan 出力について説明します。
90
Adaptive Server Enterprise
第3章
showplan の使用
文レベル出力
各クエリ・プランに関する showplan 出力の最初の部分には、文レベル情報が示
されています。次のように、クエリ・プランが生成されたクエリのバッチまた
はストアド・プロシージャの文と行番号を示すメッセージが常に存在します。
文 N (N 行目 ) のクエリ・プラン。
クエリ・プランが抽象プランを使用して生成された場合は、次に抽象プランの
使用状況に関するメッセージが表示されます。このメッセージで、抽象プラン
がどのように強制されたかがわかります。
•
SQL 文の plan 句によって明示的に抽象プランが指定された場合には、メッ
セージは次のようになります。
PLAN 句に Abstract Plan を使用して最適化しました。
•
抽象プランが内部的に生成された場合 ( 並行で実行される alter table コマ
ンドと reorg コマンドに対して生成される )、メッセージは次のようにな
ります。
強制オプション ( 内部で生成された Abstract Plan) を使って最適化し
ました。
•
抽象プランの使用が有効になっているために抽象プランが sysqueryplans
から取得された場合、メッセージは次のようになります。
Abstract Plan を使用して最適化しました。(ID : N)
•
クエリ・プランが並列クエリ・プランである場合、次のメッセージで、ク
エリ・プランの実行に必要なプロセス数 ( コーディネータおよびワーカー )
が示されます。
調整プロセスと N 作業プロセスにより並列に実行されました。
•
クエリ・プランがシミュレートされた統計情報を使用して最適化された場
合は、次のメッセージがその後に表示されます。
疑似統計を使用して最適化されました。
•
ASE は、クエリ実行中にアクセスされる各データベース・オブジェクト
に対して、スキャン記述子を使用します。接続 ( または並行クエリ・プラ
ン用の各ワーカー・プロセス ) には、デフォルトでそれぞれ 28 のスキャ
ン記述子があります。クエリ・プランでアクセスが必要なデータベース・
オブジェクトの数が 28 を超える場合は、補助スキャン記述子がグローバ
ル・プールから割り付けられます。クエリ・プランが補助スキャン記述子
を使用する場合、必要な合計数を示す次のメッセージが出力されます。
補助スキャン記述子が必要です : N
•
次のメッセージは、クエリ・プランに出現する Lava オペレータの合計数
を示します。
N operator(s) under root
クエリ・プロセッサ
91
文レベル出力
•
次のメッセージは、クエリ・プランのタイプを示しています。Lava クエ
リ・プランの場合、クエリ・タイプは、select、insert、delete、update の
いずれかです。
クエリのタイプは SELECT です。
•
Adaptive Server がリソース制限を有効にするように設定されている場合、
最後の文レベル・メッセージが showplan 出力の最後に示されます。メッ
セージには、オプティマイザによる論理 I/O と物理 I/O のコスト合計の見
積もりが示されます。
文 N (M 行目 ) の合計予想 I/O コスト:X。
次の showplan 出力のクエリは、これらのメッセージのいくつかを示しています。
1> use pubs2
1> set showplan on
1> select stores.stor_name, sales.ord_num
2> from stores, sales, salesdetail
3> where salesdetail.stor_id = sales.stor_id
4> and stores.stor_id = sales.stor_id
5> plan " ( m_join ( i_scan salesdetailind salesdetail)
6> ( m_join ( i_scan salesind sales ) ( sort ( t_scan stores )
) ))"
文 1 (1 行目 ) のクエリ・プラン。
PLAN 句に Abstract Plan を使用して最適化しました。
6 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|MERGE JOIN Operator (Join Type: Inner Join)
| ワーク・テーブル 3 を内部記憶に使用しています。
| Key Count: 1
| Key Ordering: ASC
|
|
|SCAN Operator
|
| FROM TABLE
|
| salesdetail
|
| インデックス :salesdetailind
|
| 前方スキャン
|
| インデックスの最初に位置付けます。
|
| インデックスは必要なカラムをすべて含んでいます。ベース・テー
ブルは読み込まれません。
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロバイ
トを使用しています。
92
Adaptive Server Enterprise
第3章
showplan の使用
|
| インデックス・リーフ・ページに対する LRU でのバッファ置換方式
|
|
|MERGE JOIN Operator (Join Type: Inner Join)
|
| ワーク・テーブル 2 を内部記憶に使用しています。
|
| Key Count: 1
|
| Key Ordering: ASC
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| sales
|
|
| テーブル・スキャンです。
|
|
| 前方スキャン
|
|
| テーブルの最初に位置付けます。
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用し
ています。
|
|
| データ・ページに対する LRU でのバッファ置換方式
|
|
|
|
|SORT Operator
|
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| stores
|
|
|
| テーブル・スキャンです。
|
|
|
| 前方スキャン
|
|
|
| テーブルの最初に位置付けます。
|
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使
用しています。
|
|
|
| データ・ページに対する LRU でのバッファ置換方式
文レベル出力の後にクエリ・プランが表示されます。クエリ・プランの showplan
出力は、次の 2 つのコンポーネントで構成されています。
クエリ・プロセッサ
•
クエリ・プランで実行されるオペレーション分析を示す Lava オペレータ
の名前 ( 追加情報を提供するものも存在します )。
•
クエリ・プラン・オペレータ・ツリーの形状を示すインデント付きの縦線
(“ | ” 記号 )。
93
Lava クエリ・プランの形状
Lava クエリ・プランの形状
Lava クエリ・プランは、Lava オペレータを逆向きにしたツリー構造です。ツ
リー内のそれぞれのオペレータの位置がオペレータの実行順序を示します。実
行は、ツリーの最も左側から右方向へと進行します。実行を具体的に示すため
に、ここでは、前述のクエリ・プランを例にして手順を追って説明します。
図 3-1 は、クエリ・プランを図示したものです。
図 3-1: クエリ・プラン
EmitOP
MergeJoinOp(1)
内部ジョイン
MergeJoinOp(2)
内部ジョイン
ScanOp
salesdetailind
SortOp
ScanOp
sales
ScanOp
stores
結果ローを生成するため、EmitOp はその子である MergeJoinOp(1) のローを
呼 び出 します。MergeJoinOp(1) は、その左側の子である salesdetailind の
ScanOp を呼び出します。MergeJoinOp(1) は、左側の子のローを受け取ると、
右側の子である MergeJoinOp(2) を呼び出します。MergeJoinOp(2) は、その
左側の子である sales の ScanOp を呼び出します。MergeJoinOp(2) は、左側の
子のローを受け取ると、右側の子である SortOp を呼び出します。SortOp は、
データ・ブロック・オペレータです。つまり、入力ローがすべて揃ってから入
力ローをソートできるようになるので、SortOp は、すべてのローが返される
まで子 (stores にの ScanOp) のローの呼び出しを続けます。すべてのローが
揃ったら、SortOp はローをソートし、最初の結果を MergeJoinOp(2) に戻し
ます。MergeJoinOp(2) は、ジョイン・キーに一致する 2 つのローを取得する
まで、左側または右側の子オペレータのいずれかのローを呼び出します。その
後、一致するローが MergeJoinOp(1) に戻されます。また、MergeJoinOp(1)
は、一致が見つかるまで子オペレータのローを呼び出します。見つかった結果
は、EmitOp に戻されて、それがクライアントに返されます。
図 3-2 は、同じクエリ例の別のクエリ・プランを図示したものです。このクエ
リ・プランに含まれるオペレータは前のものとすべて同じですが、ツリーの形
状が異なっています。
94
Adaptive Server Enterprise
第3章
showplan の使用
図 3-2: 別のクエリ・プラン
EmitOP
MergeJoinOp(1)
内部ジョイン
ScanOp
salesdetailind
MergeJoinOp(2)
内部ジョイン
ScanOp
sales
SortOp
ScanOp
stores
図 3-2 のクエリ・プランに対応する showplan 出力は、次のとおりです。
文 1 (1 行目 ) のクエリ・プラン。
6 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|MERGE JOIN Operator (Join Type: Inner Join)
| ワーク・テーブル 3 を内部記憶に使用しています。
| Key Count: 1
| Key Ordering: ASC
|
|
|MERGE JOIN Operator (Join Type: Inner Join)
|
| ワーク・テーブル 2 を内部記憶に使用しています。
|
| Key Count: 1
|
| Key Ordering: ASC
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| sales
|
|
| テーブル・スキャンです。
|
|
| 前方スキャン
|
|
| テーブルの最初に位置付けます。
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用し
ています。
|
|
| データ・ページに対する LRU でのバッファ置換方式
|
|
|
|
|SORT Operator
|
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| stores
クエリ・プロセッサ
95
Lava クエリ・プランの形状
|
|
|
|
|
|
|
|
|
|
|
|
テーブル・スキャンです。
前方スキャン
テーブルの最初に位置付けます。
| データ・ページに対して I/O サイズ
2 キロバイトを使用しています。
| データ・ページに対する LRU でのバッファ置換方式
|
|
|
|
|
|
|
|
|SCAN Operator
|
| FROM TABLE
|
| salesdetail
|
| インデックス :salesdetailind
|
| 前方スキャン
|
| インデックスの最初に位置付けます。
|
| インデックスは必要なカラムをすべて含んでいます。ベース・テー
ブルは読み込まれません。
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロバイ
トを使用しています。
|
| インデックス・リーフ・ページに対する LRU でのバッファ置換方式
showplan 出力は、インデントと “ | ” 記号を使用して、どのオペレータがどの
オペレータの下にあり、どれがツリーの同一の分岐または別の分岐にあるかを
示すことでクエリ・プランの形状を現します。ツリーの形状を解釈するには、
次の 2 つのルールがあります。
•
第 1 のルールは、“ | ” 記号が、オペレータの名前で始まり、同一の分岐で
そのオペレータの下にあるすべてのオペレータに対して下方向に続く縦
線を作っているということです。
•
第 2 のルールは、子オペレータが左から右の方向で示されるということ
です。
これらのルールを使用して、図 3-2 のクエリ・プランの形状は、次の手順で前
述の showplan 出力から導出することができます。
96
1
root オペレータまたは emit オペレータは、クエリ・プラン・ツリーの最上
部にあります。root は常に単一の最上位のオペレータであり、showplan 出力
の上部から下部への方向で実行されるので、root には縦線はありません。
2
マージ・ジョイン・オペレータ (MergeJoinOp(1)) は、root の左側の子で
す。MergeJoinOp(1) から始まる縦線は出力の一番下まで引かれており、
MergeJoinOp(1) の下および同一の分岐にあるすべての他のオペレータも
出力の一番下まで引かれています。
3
MergeJoinOp(1) の左側の子オペレータは、もう 1 つのマージ・ジョイン・
オペレータである MergeJoinOp(2) です。
4
MergeJoinOp(2) から始まる縦線は、scan、sort、およびもう 1 つの scan
オペレータまで下に引かれて終わっています。これらのオペレータはすべ
て MergeJoinOp(2) の下位 ( またはツリーでの下部 ) にあります。
5
MergeJoinOp(2) の最初の SCAN は、その左側の子である sales テーブル
のスキャンです。
Adaptive Server Enterprise
第3章
showplan の使用
6
SORT オペレータは MergeJoinOp(2) の右側の子であり、stores テーブル
の SCAN は SORT の唯一の子です。
7
stores テーブルの SCAN に対する出力の下では、いくつかの縦線が終了
しています。これは、ツリーの分岐が終了したことを示しています。
8
SCAN の次の出力は salesdetail テーブルです。このインデントは
MergeJoinOp(2) と同じで、同じレベルであることを示しています。事
実、この SCAN は MergeJoinOp(1) の右側の子です。
注意 ほとんどのオペレータは単項または 2 項です。つまり、そのすぐ下には、
1 つの子オペレータまたは 2 つの子オペレータのいずれかがあるということで
す。2 つの子オペレータよりも多くの子オペレータを持つオペレータを n 項オ
ペレータといいます。子を持たないオペレータは、ツリーのリーフ・オペレー
タであり、null 項オペレータといいます。
クエリ・プランを図示する別の方法として、set statistics plancost on コマンド
を使用する方法があります。詳細については、『ASE リファレンス・マニュア
ル:コマンド』を参照してください。このコマンドは、クエリ・プランの見積
もりコストと実際のコストを比較するために使用します。クエリ・プラン・ツ
リーのセミグラフィカル・ツリーとして出力を示します。
Lava オペレータ
Lava オペレータは「第 2 章 並列クエリ処理 (QP)」で紹介しており、同じ章の
表 2-1 に一覧を示しています。ここでは、各オペレータの詳細情報を示す追加
メッセージを紹介します。
Emit オペレータ
emit オペレータは、すべての Lava クエリ・プランの最上部に現れます。これ
はクエリ・プラン・ツリーの root であり、常にただ 1 つの子オペレータを持
ちます。emit オペレータは、クエリの結果ローをクライアント ( アプリケー
ションまたは別の Adaptive Server インスタンス ) に送信すること、または結果
ローの値をローカル変数または fetch into 変数に割り当てることによって、結
果ローを転送します。
クエリ・プロセッサ
97
Lava クエリ・プランの形状
Scan オペレータ
scan オペレータは、ローを Lava クエリ・プランに読み込んで、クエリ・プラ
ン内の他のオペレータでの処理にローを利用できるようにします。scan オペ
レータはリーフオペレータです。つまり、子オペレータを持つことのないオペ
レータです。scan オペレータは複数のソースからローを読み込むことができ
るので、このオペレータを識別する showplan メッセージには必ず後ろに from
メッセージがあり、それによってどのような種類の scan が実行されているの
かを識別できます。from メッセージには、3 種類、つまり、from cache、from
or list、from table があります。
from cache
このメッセージは、CacheScanOp が単一ロー・メモリ内テーブルを読み込ん
でいることを示しています。
from or list
1 つの or リストには最大 N ローの OR/IN 値があります。
最初のメッセージは、OrScanOp が、1 つの in リストまたは同一のカラムに対
する複数の or 句の値を含むメモリ内テーブルからローを読み込んでいること
を示しています。OrScanOp は、in リスト用の特殊 OR 方式を使用するクエ
リ・プランのみに出現します。2 番目のメッセージは、メモリ内テーブルが持
つことのできる最大ロー数 (N) を示しています。メモリ内テーブルへの値の挿
入時に OrScanOp では重複値が削除されるので、N は、SQL 文にある値の数
よりも少なくなる可能性があります。たとえば、次のクエリでは、特殊 OR 方
式のクエリ・プランと OrScanOp が生成されます。
1> select s.id from sysobjects s where s.id in (1, 0, 1, 2, 3)
2> go
文 1 (1 行目 ) のクエリ・プラン。
4 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|NESTED LOOP Operator (Join Type: Inner Join)
|
|
|SCAN Operator
|
| FROM OR List
|
| OR List has up to 5 rows of OR/IN values.
|
|
|SCAN Operator
|
| FROM TABLE
98
Adaptive Server Enterprise
第3章
showplan の使用
|
| sysobjects
|
| s
|
| クラスタード・インデックスを使用します。
|
| インデックス : csysobjects
|
| 前方スキャン
|
| キーによって位置付けます。
|
| インデックスは必要なカラムをすべて含んでいます。ベース・テー
ブルは読み込まれません。
|
| キー :
|
|
id ASC
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロバイ
トを使用しています。
|
| インデックス・リーフ・ページに対する LRU でのバッファ置換方式
この例では、in リストに 5 つの値が存在しますが、重複しないのは 4 つのみで
あるため、OrScanOp はその 4 つの重複しない値のみをメモリ内テーブルに入
れます。サンプル・クエリ・プランでは、OrScanOp は NLJoinOp の左側の子
オペレータであり、ScanOp は NLJoinOp の右側の子オペレータです。このプ
ランが実行されると、NLJoinOp は OrScanOp を呼び出してそのメモリ内テー
ブルのローを返し、その後、NLJoinOp は ScanOp を呼び出して、ルックアッ
プ用のクラスタード・インデックスを使用してすべての一致するローを ( 一度
に 1 つずつ ) 検出します。このサンプルのクエリ・プランは、sysobjects のロー
すべてを読み込んで各ローの sysobjects.id の値を in リスト内の 5 つの値と比
較するよりもはるかに効率的です。
from table
tablename
correlation name
from table は、PtnScanOp がデータベース・テーブルを読み込んでいることを
示します。2 番目のメッセージはテーブル名を示し、相関名が存在する場合に
は、それが次の行に出力されます。前述のサンプル出力の from table メッセー
ジの下の場合、sysobjects がテーブル名であり、s が相関名です。前述のサンプ
ルでは、from table メッセージの下にさらにいくつかの追加メッセージが示さ
れています。これらのメッセージは、PtnScanOp が Adaptive Server のアクセ
ス・レイヤに対してスキャン対象のテーブルのローを取得するよう指示する方
法についての詳細な情報を示します。
次のメッセージは、スキャンがテーブル・スキャンなのかインデックス・ス
キャンなのかを示します。
クエリ・プロセッサ
•
テーブル・スキャンです - ローがテーブルのページを読み込むことで
フェッチされることを示します。
•
クラスタード・インデックスを使用します - クラスタード・インデック
スがテーブルのローのフェッチに使用されることを示します。
99
Lava クエリ・プランの形状
•
インデックス : indexname - インデックスがテーブルのローのフェッチ
に使用されることを示します。このメッセージの前に「クラスタード・イ
ンデックスを使用します」メッセージがない場合は、ノンクラスタード・
インデックスが使用されます。indexname は、使用されるインデックスの
名前です。
これらのメッセージは、テーブル・スキャンまたはインデックス・スキャンの
方向を示します。スキャン方向は、インデックスの作成時に指定された順序や
order by 句のカラムの順序によって異なります。
後方スキャンは、order by 句がインデックス・キーの ASC 修飾子または DESC 修
飾子を、create index 句の場合とまったく逆の順序で含む場合に使用できます。
前方スキャン
後方スキャン
スキャン方向メッセージの後ろには、テーブルまたはインデックスのリーフ・
レベルへのアクセスがどのように行われるかを説明する位置付けに関する
メッセージが続きます。
•
テーブルの最初に位置付けます - テーブルの最初のローから順方向にテー
ブル・スキャンが始まることを示します。
•
テーブルの最後に位置付けます - テーブルの最後のローから逆方向にテー
ブル・スキャンが始まることを示します。
•
キーによって位置付けます - 最初に条件を満たすローのスキャンの位置
付けにインデックスを使用することを示します。
•
インデックスの最初に位置付けます
インデックスの最後に位置付けます - これらのメッセージは、テーブル・
スキャン用の対応するメッセージと似ており、テーブルではなくインデッ
クスがスキャンされる点のみが異なります。
クエリの性質によってスキャンが限定できる場合には、その後のメッセージに
その内容が示されます。
•
テーブルの最後のページだけをスキャンします - このメッセージは、ス
キャンがインデックスを使用し、スカラ集合の MAX 値を検索するときに
表示されます。最大値が検索されているカラムにインデックスが設定され
ており、そのインデックス値が昇順である場合は、最大値は最後のページ
に存在します。
•
最初に該当するローまでだけをスキャンします - このメッセージは、ス
キャンがインデックスを使用し、スカラ集合の MIN 値を検索するときに
表示されます。
注意 インデックス・キーが降順である場合、作成された先行キーがある場合、
前述の min 集合関数と max 集合関数に対応するメッセージは逆になります。
100
Adaptive Server Enterprise
第3章
showplan の使用
場合によっては、スキャンされるインデックスが、クエリで必要なテーブルの
カラムをすべて含んでいることがあります。そのような場合には、次のメッ
セージが出力されます。
インデックスは必要なカラムをすべて含んでいます。ベース・テーブルは読
み込まれません。
オプティマイザは、インデックスがクエリで必要なカラムすべてを含む場
合、インデックス・カラムに利用できるキーが存在しない場合でも、table
scan より index scan を選択することがあります。これは、インデックス
を読み込むために必要な I/O の回数が、ベース・テーブルを読み込むため
に必要な回数よりも格段に少ないためです。ベース・テーブル・ページを
読み込む必要のないインデックス・スキャンは、カバード・インデック
ス・スキャンと呼ばれます。
index scan がスキャンの位置付けにキーを使用している場合、次のメッセージ
が出力されます。
キー :
Key [ASC] [DESC]
このメッセージはキーとして使用されるカラム名 (1 行の出力行に 1 つの
キー ) とそのキーのインデックス順を示します。ASC は昇順で DESC は降
順です。
scan オペレータで使用されるアクセスのタイプを説明するメッセージの後に
は、I/O サイズとバッファ・キャッシュ方式に関するメッセージが出力されま
す。I/O メッセージは次のとおりです。
データ・ページに対して I/O サイズ N キロバイトを使用しています。
インデックス・リーフ・ページに対して I/O サイズ N キロバイトを使用し
ています。
I/O サイズのメッセージ
データ・ページに対して I/O サイズ N キロバイトを使用しています。
インデックス・リーフ・ページに対して I/O サイズ N キロバイトを使用してい
ます。
これらのメッセージは、クエリが使用する I/O サイズを出力します。I/O サイ
ズとしては、2K、4K、8K、16K を使用できます。
クエリで使われているテーブル、インデックス、LOB オブジェクト、または
データベースが大容量 I/O プールを持つデータ・キャッシュを使用する場合、
オプティマイザは大容量 I/O を選択します。インデックスのリーフ・ページを
読み込む場合は 1 つの I/O サイズを、データ・ページを読み込む場合は異なる
I/O サイズを使用するように選択できます。その選択は、キャッシュ内で使用
可能なプール・サイズ、読み込むページ数、オブジェクトのキャッシュ・バイ
ンド、テーブルやインデックス・ページのクラスタ率によって異なります。
クエリ・プロセッサ
101
Lava クエリ・プランの形状
これらのメッセージの片方または両方が scan オペレータの showplan 出力に
表示されます。テーブル・スキャンの場合は 1 番目のメッセージのみが出力さ
れ、カバード・インデックス・スキャンの場合は 2 番目のメッセージのみが出
力されます。ベース・テーブル・アクセスを必要とする index scan では、両
方のメッセージが出力されます。
それぞれの I/O サイズ・メッセージの後には、キャッシュ方式メッセージが出
力されます。
データ・ページに対する <LRU/MRU> でのバッファ置換方式
インデックス・リーフ・ページに対する <LRU/MRU> でのバッファ置換方式
次のクエリに、サンプルの I/O とキャッシュのメッセージを示します。
1>
1>
1>
2>
use pubs2
set showplan on
select au_fname, au_lname, au_id from authors
where au_lname = "Williams"
文 1 (1 行目 ) のクエリ・プラン。
1 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SCAN Operator
| FROM TABLE
| authors
| インデックス : aunmind
| 前方スキャン
| キーによって位置付けます。
| キー :
|
au_lname ASC
| インデックス・リーフ・ページに対して I/O サイズ 2 キロバイトを使
用しています。
| インデックス・リーフ・ページに対する LRU でのバッファ置換方式
| データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
| データ・ページに対する LRU でのバッファ置換方式
authors テーブルの scan ではインデックス aunmind が使用されますが、authors
の必要なカラムすべてを取得するためにベース・テーブル・ページを読み込む
必要もあります。この例では、I/O サイズ・メッセージが 2 つあり、それぞれ
の後ろに対応するバッファ置換メッセージが続きます。
最後に、rid scan と log scan というテーブル scan オペレータの 2 つの特殊な
種類があります。
102
Adaptive Server Enterprise
第3章
showplan の使用
RID スキャン
RID スキャンは、オプティマイザが選択できる 2 番目の or 方式である、汎用
or 方式を使用するクエリ・プランのみに存在します。汎用 or 方式は、異なる
カラムに複数の or 句が存在する場合に選択されることがあります。次に示す
のは、オプティマイザが汎用 or 方式を選択できるクエリとその showplan 出力
の例です。
1> use pubs2
1> set showplan on
1> select id from sysobjects where id = 4 or name = 'foo'
文 1 (1 行目 ) のクエリ・プラン。
6 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|RID JOIN Operator
| ワーク・テーブル 2 を内部記憶に使用しています。
|
|
|HASH UNION Operator has 2 children.
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| sysobjects
|
|
| クラスタード・インデックスを使用します。
|
|
| インデックス :csysobjects
|
|
| 前方スキャン
|
|
| キーによって位置付けます。
|
|
| インデックスは必要なカラムをすべて含んでいます。ベース・
テーブルは読み込まれません。
|
|
| キー :
|
|
|
id ASC
|
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロ
バイトを使用しています。
|
|
| インデックス・リーフ・ページに対する LRU でのバッファ置
換方式
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| sysobjects
|
|
| インデックス : ncsysobjects
|
|
| 前方スキャン
|
|
| キーによって位置付けます。
|
|
| インデックスは必要なカラムをすべて含んでいます。ベース・
テーブルは読み込まれません。
|
|
| キー :
クエリ・プロセッサ
103
Lava クエリ・プランの形状
|
|
|
name ASC
|
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロ
バイトを使用しています。
|
|
| インデックス・リーフ・ページに対する LRU でのバッファ置
換方式
|
|
|RESTRICT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| sysobjects
|
|
| 動的インデックスを使用します。
|
|
| 前方スキャン
|
|
| ロー識別子 (RID) によって位置付けます。
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用し
ています。
|
|
|
データ・ページに対する LRU でのバッファ置換方式
この例で、where 句には、それぞれが異なるカラム (id と name) にある 2 つの
分離が含まれています。これらのカラムにはそれぞれインデックスがあり
(csysobjects と ncsysobjects)、そのため、オプティマイザは、id カラムが 4 で
あるすべてのローを検出するためのインデックス・スキャンと、name が “foo”
であるすべてのローを検出するための別のインデックス・スキャンを使用する
クエリ・プランを選択しました。1 つのローの id が 4 で、かつ name が “foo”
である可能性があるため、そのローは結果セットに 2 回表示されることになり
ます。これらの重複ローを削除するため、インデックス・スキャンは条件を満
たすローのロー識別子 (RID) のみを返します。RID の 2 つのストリームは hash
union オペレータによって連結されます。このオペレータは、重複した RID の
削除も行います。ユニークな RID のストリームは rid join オペレータに渡され
ます。rid join オペレータはワーク・テーブルを作成し、各 RID に単一カラム・
ローを埋め込みます。rid join オペレータは、次に、その RID のワーク・テー
ブルを rid scan オペレータに渡します。rid scan オペレータはアクセス・レイ
ヤにワーク・テーブルを渡します。アクセス・レイヤでは、ワーク・テーブル
はキーのないノンクラスタード・インデックスとして扱われ、RID に対応する
ローがフェッチされて返されます。showplan 出力の最後の scan は、rid scan
です。サンプル出力でもわかるように、rid scan 出力には、これまで説明した
多くのメッセージが含まれており、また、rid scan のみで出力される次の 2 つ
のメッセージも含まれています。
104
•
動的インデックスを使用します - このメッセージは、一致するローを検
索するためのインデックスとして rid join オペレータによって実行中に構
築された RID とともに scan がワーク・テーブルを使用していることを示
しています。
•
ロー識別子 (RID) によって位置付けます - このメッセージは、ローが
RID によって直接検索されることを示しています。
Adaptive Server Enterprise
第3章
showplan の使用
log スキャン
log スキャンは、挿入または削除されるテーブルにアクセスするトリガのみに
出現します。挿入または削除されるテーブルは、トリガが実行されるときにト
ランザクション・ログをスキャンすることによって動的に構築されます。トリ
ガは、insert、delete、または update クエリが、特定のクエリ・タイプ用に
テーブルに定義されているトリガによってそのテーブルを変更した後にのみ
実行されます。次の例は、titles テーブルに対する delete クエリであり、この
テーブルには deltitle という削除トリガが定義されています。
1> use pubs2
1> set showplan on
1> delete from titles where title_id = 'xxxx'
文 1 (1 行目 ) のクエリ・プラン。
2 operator(s) under root
クエリのタイプは DELETE です。
ROOT:EMIT Operator
|DELETE Operator
| 直接更新モードです。
|
|
|SCAN Operator
|
| FROM TABLE
|
| titles
|
| クラスタード・インデックスを使用します。
|
| インデックス :titleidind
|
| 前方スキャン
|
| キーによって位置付けます。
|
| キー :
|
|
title_id ASC
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用してい
ます。
|
| データ・ページに対する LRU でのバッファ置換方式
|
| TO TABLE
| titles
| データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
ここまでの showplan 出力は、実際の delete クエリ用です。これ以降の出力
は、トリガである deltitle 用です。
文 1 (5 行目 ) のクエリ・プラン。
6 operator(s) under root
クエリのタイプは COND です。
ROOT:EMIT Operator
クエリ・プロセッサ
105
Lava クエリ・プランの形状
|RESTRICT Operator
|
|
|SCALAR AGGREGATE Operator
|
| グループ化されていない COUNT AGGREGATE を評価します。
|
|
|
|
|MERGE JOIN Operator (Join Type: Inner Join)
|
|
| ワーク・テーブル 2 を内部記憶に使用しています。
|
|
| Key Count: 1
|
|
| Key Ordering: ASC
|
|
|
|
|
|
|SORT Operator
|
|
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
| FROM TABLE
|
|
|
|
| titles
|
|
|
|
| ログ・スキャンです。
|
|
|
|
| 前方スキャン
|
|
|
|
| テーブルの最初に位置付けます。
|
|
|
|
| データ・ページに対して I/O サイズ 2 キロバイ
トを使用しています。
|
|
|
|
| データ・ページに対する MRU でのバッファ置換方式
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| salesdetail
|
|
|
| インデックス :titleidind
|
|
|
| 前方スキャン
|
|
|
| インデックスの最初に位置付けます。
|
|
|
| インデックスは必要なカラムをすべて含んでいます。ベー
ス・テーブルは読み込まれません。
|
|
|
| インデックス・リーフ・ページに対して I/O サイズ 2
キロバイトを使用しています。
|
|
|
| インデックス・リーフ・ページに対する
LRU でのバッファ置換方式
文 2 (8 行目 ) のクエリ・プラン。
STEP 1
クエリのタイプは ROLLBACK TRANSACTION です。
文 3 (9 行目 ) のクエリ・プラン。
STEP 1
クエリのタイプは PRINT です。
文 4 (0 行目 ) のクエリ・プラン。
STEP 1
クエリのタイプは GOTO です。
106
Adaptive Server Enterprise
第3章
showplan の使用
トリガ deltitle を定義するプロシージャは、4 つの SQL 文で構成されます ( ト
リガ定義の SQL テキストは、sp_helptext deltitle コマンドで表示できます )。
deltitle の最初の文は、Lava クエリ・プランにコンパイルされていますが、そ
れ以外の 3 つの文は従来のクエリ・プランにコンパイルされ、Lava クエリ実
行エンジンではなく手続き型クエリ実行エンジンによって実行されます。
titles テーブルに対する scan オペレータの showplan 出力は、「ログ・スキャ
ンです 」というメッセージを出力することによって、それがログのスキャン
を行っていることを示します。
delete、insert、update オペレータ
DML オペレータは通常、子オペレータを 1 つしか持ちません。ただし、参照
整合性制約を実現するためと、テキスト・カラムの alter table drop の場合の
テキスト・データの割り付けを解除するために、追加として最大 2 つの子オペ
レータを持つことができます。
DML オペレータは、ターゲット・テーブルに属しているローの挿入、削除、
または更新によってデータを変更します。
DML オペレータの子オペレータには、scan オペレータ、join オペレータ、ま
たは任意のデータ・ストリーミング・オペレータを指定できます。
データ変更は、次のメッセージで示される異なる更新モードを使用して実行で
きます。
更新モードは < Update Mode> です。
テーブル更新モードは、直接、遅延、インデックス用遅延、可変長カラム用遅
延のいずれかになります。ワーク・テーブルの更新モードは常に直接更新モー
ドです。詳細については、
『パフォーマンス&チューニング・ガイド』を参照
してください。
データ変更用のターゲット・テーブルは、次のメッセージで表示されます。
TO TABLE
<Table Name>
ここでは、データ変更に使用される I/O サイズも表示されます。
データ・ページに対して I/O サイズ <N> キロバイトを使用しています。
次の例では、delete DML オペレータが使用されています。
1>
2>
1>
2>
1>
2>
use pubs2
go
set showplan on
go
delete from authors where postalcode = '90210'
go
文 1 (1 行目 ) のクエリ・プラン。
2 operator(s) under root
クエリ・プロセッサ
107
Lava クエリ・プランの形状
クエリのタイプは DELETE です。
ROOT:EMIT Operator
|DELETE Operator
| 直接更新モードです。
|
|
|SCAN Operator
|
| FROM TABLE
|
| authors
|
| テーブル・スキャンです。
|
| 前方スキャン
|
| テーブルの最初に位置付けます。
|
| データ・ページに対して I/O サイズ 4 キロバイトを使用してい
ます。
|
| データ・ページに対する LRU でのバッファ置換方式
|
| TO TABLE
| authors
| データ・ページに対して I/O サイズ 4 キロバイトを使用しています。
text delete オペレータ
DML オペレータが複数の子オペレータを持つことのできるもう 1 つのタイプ
のクエリ・プランは alter table drop textcol コマンドです。このとき、textcol
はデータ型が text、image、または unitext であるカラムの名前です。次のクエ
リとクエリ・プランは、text delete オペレータの使用例です。
1>
1>
1>
1>
use tempdb
create table t1 (c1 int, c2 text, c3 text)
set showplan on
alter table t1 drop c2
文 1 (1 行目 ) のクエリ・プラン。
PLAN 句に Abstract Plan を使用して最適化しました。
5 operator(s) under root
クエリのタイプは ALTER TABLE です。
ROOT:EMIT Operator
|INSERT Operator
| 直接更新モードです。
|
|
|RESTRICT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| t1
108
Adaptive Server Enterprise
第3章
showplan の使用
|
|
| テーブル・スキャンです。
|
|
| 前方スキャン
|
|
| テーブルの最初に位置付けます。
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用し
ています。
|
|
| データ・ページに対する LRU でのバッファ置換方式
|
|
|TEXT DELETE Operator
|
| 直接更新モードです。
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| t1
|
|
| テーブル・スキャンです。
|
|
| 前方スキャン
|
|
| テーブルの最初に位置付けます。
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用し
ています。
|
|
| データ・ページに対する LRU でのバッファ置換方式
|
| TO TABLE
| #syb__altab
| データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
この例では、t1 の 2 つの text カラムのうちの 1 つが、alter table コマンドを使
用して削除されています。showplan 出力は、alter table が内部で select into ク
エリ・プランを生成しているため、select into クエリ・プランに似ています。
insert オペレータは、その左側の子オペレータである t1 の scan オペレータを
呼び出して、t1 のローを読み込み、#syb_altab に c1 カラムと c3 カラムのみ
が挿入される新しいローを構築します。新しいローがすべて #syb_altab に挿
入されると、insert オペレータはその右側の子オペレータである text delete オ
ペレータを呼び出して、t1 から削除された c2 カラム用のテキスト・ページ・
チェーンを削除します。後処理によって t1 の元のページが #syb_altab のペー
ジに置き換えられて、alter table コマンドが完了します。
クエリ・プロセッサ
•
text delete オペレータは、削除を行う alter table コマンドにしか出現しま
せんが、テーブルのすべてのテキスト・カラムで出現するわけではありま
せん。また、必ず insert オペレータの右側の子として出現します。
•
deltext オペレータは、update、delete、insert オペレータとまったく同じ
ように更新モード・メッセージを表示します。
109
Lava クエリ・プランの形状
参照整合性実現のためのクエリ・プラン
insert、delete、または update オペレータが 1 つ以上の参照整合性制約のある
テーブルに対して処理を行うと、その showplan 出力には 1 つまたは 2 つの
DML オペレータの子オペレータが追加で表示されます。この 2 つの追加オペ
レータは、direct ri filter オペレータと deferred ri filter オペレータです。参照整
合性制約の種類によって、これらのオペレータのいずれかまたは両方が存在す
ることが決まります。
次は、pubs3 データベースの titles テーブルへの insert の例です。このテーブ
ルには、publishers テーブルの pub_id カラムを参照する pub_id というカラム
があります。titles.pub_id の参照整合性制約では、titles.pub_id に挿入される
すべての値が publishers.pub_id で対応する値を持っていることが必要です。
クエリとそのクエリ・プランは次のとおりです。
1> use pubs3
1> set showplan on
1> insert into titles values ("AB1234", "Abcdefg", "test",
"9999", 9.95, 1000.00, 10, null, getdate(),1)
文 1 (1 行目 ) のクエリ・プラン。
4 operator(s) under root
クエリのタイプは INSERT です。
ROOT:EMIT Operator
|INSERT Operator
| 直接更新モードです。
|
|
|SCAN Operator
|
| FROM CACHE
|
|
|DIRECT RI FILTER Operator has 1 children.
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| publishers
|
|
| インデックス : publishers_6240022232
|
|
| 前方スキャン
|
|
| キーによって位置付けます。
|
|
| インデックスは必要なカラムをすべて含んでいます。ベース・
テーブルは読み込まれません。
|
|
| キー :
|
|
|
pub_id ASC
|
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロ
バイトを使用しています。
|
|
| インデックス・リーフ・ページに対する LRU でのバッファ置
換方式
|
110
Adaptive Server Enterprise
第3章
|
|
|
showplan の使用
TO TABLE
titles
データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
クエリ・プランでは、insert オペレータの左側の子オペレータが cache scan で
あり、これが titles に挿入される値のローを返します。insert オペレータの右
側の子は direct ri filter オペレータです。direct ri filter オペレータは publishers
テーブルのスキャンを実行して、titles に挿入される予定の pub_id の値と一致
する pub_id の値のローを検索します。一致するローが見つかった場合、direct
ri filter オペレータによって、insert の処理の続行が許可されますが、publishers
で pub_id と一致する値が見つからなかった場合には、direct ri filter オペレー
タはコマンドをアボートします。この例で、direct ri filter は、挿入される各
ローに対して、そのローが挿入されるときに titles の参照整合性制約を確認し、
実現できます。
次の例は、異なるモードで動作する direct ri filter を、deferred ri filter オペレー
タとともに示しています。
1> use pubs3
1> set showplan on
1> update publishers set pub_id = '0001'
文 1 (1 行目 ) のクエリ・プラン。
13 operator(s) under root
クエリのタイプは UPDATE です。
ROOT:EMIT Operator
|UPDATE Operator
| 更新モードは deferred_index です。
|
|
|SCAN Operator
|
| FROM TABLE
|
| publishers
|
| テーブル・スキャンです。
|
| 前方スキャン
|
| テーブルの最初に位置付けます。
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用してい
ます。
|
| データ・ページに対するLRU でのバッファ置換方式
|
|
|DIRECT RI FILTER Operator has 1 children.
|
|
|
|
|INSERT Operator
|
|
| 直接更新モードです。
|
|
|
|
|
|
|SQFILTER Operator has 2 children.
|
|
|
|
|
|
|
|
|SCAN Operator
クエリ・プロセッサ
111
Lava クエリ・プランの形状
|
|
|
|
| FROM CACHE
|
|
|
|
|
|
|
| サブクエリ 1 の実行 ( ネスト・レベル 0)
|
|
|
|
|
|
|
| サブクエリ 1 に対するクエリ・プラン ( ネスト・レベ
ル 0、0 行目 )
|
|
|
|
|
|
|
|
非相関サブクエリ。
|
|
|
|
EXISTS 述語内のサブクエリ。
|
|
|
|
|
|
|
|
|SCALAR AGGREGATE Operator
|
|
|
|
| グループ化されていない ANY AGGREGATE を評価
します。
|
|
|
|
| 最初に該当するローまでだけをスキャンします。
|
|
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
|
| FROM TABLE
|
|
|
|
|
| titles
|
|
|
|
|
| テーブル・スキャンです。
|
|
|
|
|
| 前方スキャン
|
|
|
|
|
| テーブルの最初に位置付けます。
|
|
|
|
|
| データ・ページに対して I/O サイズ 2 キロ
バイトを使用しています。
|
|
|
|
|
| データ・ページに対する LRU でのバッファ置
換方式
|
|
|
|
|
|
|
| サブクエリ 1 に対するクエリ・プラン終了
|
|
|
|
|
| TO TABLE
|
|
| ワーク・テーブル 1
|
|
|DEFERRED RI FILTER Operator has 1 children.
|
|
|
|
|SQFILTER Operator has 2 children.
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| ワーク・テーブル 1
|
|
|
| テーブル・スキャンです。
|
|
|
| 前方スキャン
|
|
|
| テーブルの最初に位置付けます。
|
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使
用しています。
|
|
|
| データ・ページに対する LRU でのバッファ置換方式
|
|
|
|
|
| サブクエリ 1 の実行 ( ネスト・レベル 0)
|
|
|
|
|
| サブクエリ 1 に対するクエリ・プラン ( ネスト・レベル 0、
0 行目 )
112
Adaptive Server Enterprise
第3章
showplan の使用
|
|
|
|
|
|
非相関サブクエリ。
|
|
|
EXISTS 述語内のサブクエリ。
|
|
|
|
|
|
|SCALAR AGGREGATE Operator
|
|
|
| グループ化されていない ANY AGGREGATE を評価します。
|
|
|
| 最初に該当するローまでだけをスキャンします。
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
| FROM TABLE
|
|
|
|
| publishers
|
|
|
|
| インデックス : publishers_6240022232
|
|
|
|
| 前方スキャン
|
|
|
|
| キーによって位置付けます。
|
|
|
|
| インデックスは必要なカラムをすべて含んでいます。
ベース・テーブルは読み込まれません。
|
|
|
|
| キー :
|
|
|
|
|
pub_id ASC
|
|
|
|
| インデックス・リーフ・ページに対して I/O サイ
ズ 2 キロバイトを使用しています。
|
|
|
|
| インデックス・リーフ・ページに対する LRU での
バッファ置換方式
|
|
|
|
|
| サブクエリ 1 に対するクエリ・プラン終了
|
| TO TABLE
| publishers
| データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
最初の例にあるように、titles に対する参照整合性制約は、titles.pub_id のそれ
ぞれの値に対して publishers.pub_id. の値が存在することを必要とします。た
だし、このサンプル・クエリは、publisher.pub_id の値を変更しているので、
参照整合性制約を維持するためにはチェックを行う必要があります。サンプ
ル・クエリは、publishers のいくつかのローに対して publishers.pub_id の値を
変更することが可能なので、titles.pub_id の値すべてが publisher.pub_id に引
き続き存在することを確認するチェックは publishers のすべてのローが処理さ
れるまで実行できません。このサンプルは、遅延参照整合性チェックを呼び出
します。つまり、publishers の各ローが読み込まれると、update オペレータは
direct ri filter オペレータに呼び出しを行い、変更される予定の値と pub_id の
同じ値であるローを titles に対して検索します。ローが見つかった場合、それ
は、pub_id のこの値が引き続き publishers に存在して titles の参照整合性制約
を維持しているということなので、pub_id の値は ワーク・テーブル 1 に挿入
されます。
クエリ・プロセッサ
113
Lava クエリ・プランの形状
publishers のすべてのローが更新された後、update オペレータが deferred ri
filter オペレータに対して呼び出され、ワーク・テーブル 1 のすべての値が
publishers に引き続き存在することを確認するためにそのサブクエリが実行さ
れます。deferred ri filter の左側の子オペレータは ワーク・テーブル 1 のロー
を読み込む scan であり、右側の子オペレータは、publishers の一致する値を
チェックするために存在確認のサブクエリを実行する sq filter オペレータで
す。一致する値が見つからない場合、コマンドはアボートします。
前述の例は、2 つのテーブルのみの間の簡単な参照整合性制約を使用していま
す。Adaptive Server は、1 つのテーブルで最大 192 の制約を許可しているので、
より複雑なクエリ・プランを生成することが可能です。複数の制約を実現する
必要があるとき、クエリ・プランには単一の direct ri filter または deferred ri
filter オペレータのみが引き続き存在しますが、これらのオペレータは実現が
必要な各制約に 1 つという複数のサブプランを持つことができます。
join オペレータ
Adaptive Server Enterprise 15.0 は、3 つの主要なジョイン方式を提供しています。そ
の 3 つとは、NestedLoopJoin、MergeJoin、HashJoin です。以前のバージョンで
は、NestedLoopJoin が主要なジョイン方式でした。MergeJoin も利用することは
できましたが、デフォルトでは有効になっていませんでした。Adaptive Server
Enterprise 15.0 では、4 番目のジョイン方式である NaryNestedJoin を提供していま
す。これは NestedLoopJoin の変形です。
それぞれのジョイン・オペレータの詳細について、これ以降で説明します。各
アルゴリズムについて一般的な説明を示します。これらの説明は、各ジョイン
方式に必要な高レベルの処理概要を示します。ただし、これらの方式に適用さ
れた詳細なパフォーマンスの強化については説明しません。
NestedLoopJoin
NestedLoopJoin は、最も簡単なジョイン方式です。これは 2 項であり、左側
の子が外部データ・ストリームになり、右側の子が内部データ・ストリーム
になります。外部データ・ストリームのすべてのローに対して、内部データ・
ストリームがオープンされます。多くの場合、右側の子が scan になります。
内部データ・ストリームをオープンすることが、すべての探索引数 (SARG) の
条件を満たす最初のローに対するスキャンの効果的な位置付けを行います。
条件を満たすローは NestedLoopJoin の親オペレータに返されます。このジョ
イン・オペレータへのその後の呼び出しは、引き続き内部ストリームの条件
を満たすローを返します。現在の外部ローに対する内部ストリームの条件を
満たす最後のローが返された後、内部ストリームはクローズされます。外部
ストリームの次の条件を満たすローを取得するための呼び出しが行われま
す。このローの値は、内部ストリームのスキャンをオープンし、位置付けす
るために使用される SARG を提供します。この処理は、NestedLoopJoin の右
側の子が End Of Scan (EOS) を返すまで続きます。
114
Adaptive Server Enterprise
第3章
1>
2>
3>
4>
5>
6>
showplan の使用
-- Collect all of the title ids for books written by "Bloom".
select ta.title_id
from titleauthor ta, authors a
where a.au_id = ta.au_id
and au_lname = "Bloom"
go
文 1 (2 行目 ) のクエリ・プラン。
3 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|NESTED LOOP Operator (Join Type: Inner Join)
|
|
|SCAN Operator
|
| FROM TABLE
|
| authors
|
| a
|
| インデックス : aunmind
|
| 前方スキャン
|
| キーによって位置付けます。
|
| キー :
|
|
au_lname ASC
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロバイ
トを使用しています。
|
| インデックス・リーフ・ページに対する LRU でのバッファ置換方式
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用してい
ます。
|
| データ・ページに対する LRU でのバッファ置換方式
|
|
|SCAN Operator
|
| FROM TABLE
|
| titleauthor
|
| ta
|
| クラスタード・インデックスを使用します。
|
| インデックス : taind
|
| 前方スキャン
|
| キーによって位置付けます。
|
| キー :
|
|
au_id ASC
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用してい
ます。
|
| データ・ページに対する LRU でのバッファ置換方式
クエリ・プロセッサ
115
Lava クエリ・プランの形状
この例では、authors テーブルが titleauthor テーブルとジョインされています。
NestedLoopJoin 方式が選択されています。NestedLoopJoin オペレータのタイ
プが「内部ジョイン」であることに注意してください。最初に、authors テー
ブルがオープンされ、l_name の値が “Bloom” である最初のローに位置付けら
れます (aunmind インデックスが使用されます )。次に、titleauthor テーブルが
オープンされ、クラスタード・インデックス “taind” を使用して、現在の authors
のローの au_id 値と同じ au_id の最初のローに位置付けられます。内部スト
リームのルックアップに利用できるインデックスが存在しない場合、オプティ
マイザが再フォーマット方式を生成することがあります。
一般に、Nested Loop Join 方式は、外部ストリームのローが比較的少なく、内
部ストリームへの探索に利用できる効果的なインデックスが利用できる場合
に効果があります。
MergeJoin
MergeJoin オペレータは 2 項オペレータです。左側の子は外部データ・スト
リームであり、右側の子は内部データ・ストリームです。どちらのデータ・ス
トリームもマージジョインのキー値でソートされる必要があります。まず、外
部ストリームのローがフェッチされます。これによってマージジョインのジョ
イン・キー値が初期化されます。次に、一致するかより大きい ( キーが降順の
場合はより小さい ) キー値のローが検出されるまで、内部ストリームのローが
フェッチされます。ジョイン・キーが一致すると、条件を満たすローが後の処
理に渡され、その後ろに続くマージジョイン・オペレータへの次の呼び出しが
現在アクティブなストリームのフェッチを続行します。新しい値が現在の比較
キーよりも大きな場合、他のストリームのローをフェッチするときにこれらの
値が新しい比較ジョイン・キーとして使用されます。このプロセスは、デー
タ・ストリームのいずれかがなくなるまで続行されます。
一般に、MergeJoin 方式は、データ・ストリームのスキャンでローのほとんど
を処理する必要があり、ストリームの片方または両方がすでにジョイン・キー
でソートされているときに効果的です。
1>
2>
3>
4>
5>
6>
-- Collect all of the title ids for books written by "Bloom".
select ta.title_id
from titleauthor ta, authors a
where a.au_id = ta.au_id
and au_lname = "Bloom"
go
文 1 (2 行目 ) のクエリ・プラン。
STEP 1
クエリのタイプは EXECUTE です。
新しくキャッシュされた文を実行中です。
文 1 (2 行目 ) のクエリ・プラン。
4 operator(s) under root
116
Adaptive Server Enterprise
第3章
showplan の使用
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|MERGE JOIN Operator (Join Type: Inner Join)
| ワーク・テーブル 2 を内部記憶に使用しています。
| Key Count: 1
| Key Ordering: ASC
|
|
|SORT Operator
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| authors
|
|
| a
|
|
| インデックス : aunmind
|
|
| 前方スキャン
|
|
| キーによって位置付けます。
|
|
| キー :
|
|
|
au_lname ASC
|
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロ
バイトを使用しています。
|
|
| インデックス・リーフ・ページに対する LRU でのバッファ置
換方式
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用し
ています。
|
|
| データ・ページに対する LRU でのバッファ置換方式
|
|
|SCAN Operator
|
| FROM TABLE
|
| titleauthor
|
| ta
|
| インデックス : auidind
|
| 前方スキャン
|
| インデックスの最初に位置付けます。
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロバイ
トを使用しています。
|
| インデックス・リーフ・ページに対する LRU でのバッファ置換方式
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用してい
ます。
|
| データ・ページに対する LRU でのバッファ置換方式
この例では、ソート・オペレータが左側の子で外部ストリームです。ソート・
オペレータのデータ・ソースは、authors テーブルです。ソート・オペレータ
は、authors テーブルが、インデックスを指定していれば必要なソート順を提
供する au_id に対してインデックスを指定していないため、必要になります。
titleauthor テーブルのスキャンは、右側の子で内部ストリームになります。こ
のスキャンは、MergeJoin 方式に必要な順序を提供する auidind インデックス
を使用します。
クエリ・プロセッサ
117
Lava クエリ・プランの形状
ローが外部ストリームからフェッチされて (authors テーブルが元のソース )、
初期ジョイン・キー比較値が確立されます。その後、比較キーと同じかそれよ
りも大きなジョイン・キーのローが見つかるまで、titleauthor テーブルからロー
がフェッチされます。
一致するキーを含む内部ストリーム・ローは、再フェッチされる場合に備えて
キャッシュに格納されます。これらのローは、外部ストリームに重複キーが含
まれるときには再フェッチされます。現在のジョイン・キー比較値よりも大き
な titleauthor.au_id 値がフェッチされると、MergeJoin オペレータが外部スト
リームからのフェッチを開始し、現在の titleauthor.au_id 値と同じかそれより
も大きなジョイン・キー値が見つかるまで続行されます。ジョイン・キーが見
つかった時点で内部ストリームのスキャンが再開されます。
MergeJoin オペレータの showplan 出力には、内部ストリームの補助記憶にど
のワーク・テーブルが使用されるのかを示すメッセージが含まれています。重
複ジョイン・キーのある内部ローがキャッシュ・メモリに収まらなくなった場
合には、ワーク・テーブルへの書き込みが行われます。キャッシュ・ローの幅
は 64KB に制限されています。
HashJoin
Hash Join オペレータは 2 項オペレータです。左側の子は、ビルド入力スト
リームを生成します。右側の子は、プローブ入力ストリームを生成します。ビ
ルド・セットは、Hash Join オペレータから最初のローが要求されたときにビ
ルド入力ストリームを完全に排出することによって生成されます。すべての
ローは入力ストリームから読み込まれ、ハッシュ・キーを使用して適切なバ
ケットにハッシュされます。ビルド・セット全体を保持するのに十分なメモリ
がない場合には、その一部がディスクに書き出されます。ディスクに書き出さ
れた部分は「ハッシュ分割」と呼ばれています。これをテーブル分割と混同し
ないでください。ハッシュ分割はハッシュ・バケットの集合です。左側の子の
ストリーム全体がすべて排出された後、プローブ入力が読み込まれます。
プローブ・セットの各ローはハッシュされます。対応するビルド・バケットに
ルックアップが実行されて、ハッシュ・キーの一致するローがあるかどうかが
チェックされます。これは、ビルド・セットのバケットがメモリ上に存在する
場合に発生します。ディスクに書き出されている場合には、書き出された対応
するプローブ分割にプローブ・ローが書き込まれます。プローブ・ローのキー
がビルド・ローのキーと一致すると、2 つのローのカラムの必要な射影がその
後の処理に渡されます。
ディスクに書き出された分割は、その後に続くハッシュ・ジョイン・アルゴリ
ズムの再帰的パスで処理されます。新しいハッシュのシードは、データが異な
るハッシュ・バケットに再分配されるように各パスで使用されます。この再帰
的処理は、ディスクに書き出された最後の分割が完全にメモリ常駐になるまで
続行されます。ビルド・セットのハッシュ分割に複数の重複が含まれるように
なると、ハッシュ・ジョイン・オペレータは、ネスト・ループ・ジョイン処理
に戻ります。
118
Adaptive Server Enterprise
第3章
showplan の使用
一般に、hash join 方式は、ソース・セットのローのほとんどを処理する必要
があり、ジョイン・キーで利用できる継承された順序が存在せず、呼び出し側
のオペレータに拡大できる有益な順序 ( ジョイン・キーに対する order by 句な
ど ) が存在しない場合には、適切な方式です。ハッシュ・ジョインは、デー
タ・セットの 1 つがメモリ常駐になる程度に小さい場合には特に効果的に動作
します。この場合、ディスクへの書き出しは発生せず、ハッシュ・ジョイン・
メカニズムを実行するために必要な I/O も発生しません。
1> -- Collect all of the title ids for books written by "Bloom".
2> select ta.title_id
3>
from titleauthor ta, authors a
4> where a.au_id = ta.au_id
5>
and au_lname = "Bloom"
文 1 (2 行目 ) のクエリ・プラン。
3 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|HASH JOIN Operator (Join Type: Inner Join)
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|SCAN Operator
|
| FROM TABLE
|
| authors
|
| a
|
| インデックス : aunmind
|
| 前方スキャン
|
| キーによって位置付けます。
|
| キー :
|
|
au_lname ASC
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロバイ
トを使用しています。
|
| インデックス・リーフ・ページに対する LRU でのバッファ置換方式
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用してい
ます。
|
| データ・ページに対する LRU でのバッファ置換方式
|
|
|SCAN Operator
|
| FROM TABLE
|
| titleauthor
|
| ta
|
| インデックス : auidind
|
| 前方スキャン
|
| インデックスの最初に位置付けます。
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロバイ
トを使用しています。
|
| インデックス・リーフ・ページに対する LRU でのバッファ置換方式
クエリ・プロセッサ
119
Lava クエリ・プランの形状
|
ます。
|
|
データ・ページに対して I/O サイズ 2 キロバイトを使用してい
|
データ・ページに対する LRU でのバッファ置換方式
この例では、ビルド入力ストリームのソースは author.aunmind のインデック
ス・スキャンです。au_lname の値が “Bloom” であるローのみがこのスキャン
で返されます。これらのローは、その後、au_id 値にハッシュされ、対応する
ハッシュ・バケットに位置付けられます。初期ビルド・フェーズが完了する
と、プローブ・ストリームがオープンされ、スキャンされます。ソース・イン
デックス titleauthor.auidind の各ローは、au_id カラムでハッシュされます。結
果のハッシュ値は、一致するハッシュ・キーに対してビルド・セット内のどの
バケットを検索すべきかを判断するために使用されます。ビルド・セットの
ハッシュ・バケットからの各ローは、等価であるかについてプローブ・ローの
ハッシュ・キーと比較されます。ローが一致すると、titleauthor.au_id カラム
が Emit オペレータに戻されます。
Hash Join オペレータの showplan 出力には、ディスクに書き出された分割の補
助記憶にどのワーク・テーブルが使用されるのかを示すメッセージが含まれて
います。入力ローの幅は 64KB に制限されています。
NaryNestedLoopJoin オペレータ
Nary Nested Loop Join 方式は、オプティマイザによる評価や選択の行われない
方式です。これは、コード生成中に構築されるオペレータです。コンパイラ
は、連続する 2 つ以上の左に深いネスト・ループ・ジョインを検出した場合、
それらを Nary Nested Loop Join オペレータに変形しようとします。変形スキャ
ンには、さらに 2 つの要件があります。つまり、各 Nested Loop Join オペレー
タが「内部ジョイン」タイプを持つことと、ネスト・ループ・ジョインの右側
の子が Scan オペレータであることです。Restrict オペレータは Scan オペレー
タに対して許可されています。
Nary Nested Loop Join の実行は、複数回の Nested Loop Join オペレータの実行に
比べてパフォーマンスの上で利点があります。次の例がこれを示しています。
この 2 つの方法の実行には基本的な相違点が 1 つあります。複数回の Nested
Loop Join を行うと、スキャンが前のスキャンで初期化された SARG 値を基に
したローを削除することがあります。そのスキャンは、失敗したスキャンの直
前に行われたのではない可能性があります。複数回の Nested Loop Join では、
失敗したスキャンには何ら影響がないにもかかわらず、以前のスキャンが完全
に排出されることになります。これは、不必要な I/O の回数を大幅に増やす結
果になります。Nary Nested Loop Join では、フェッチされる次のローは失敗し
た SARG 値によって生成されたスキャンからのものです。この方がはるかに
効率的です。
1>
2>
3>
4>
5>
6>
120
-- Collect the author id and name for all authors with the
-- last name "Bloom" and who have a listed title and the
-- author id is the same as the title_id.
select a.au_id, au_fname, au_lname
from titles t, titleauthor ta, authors a
where a.au_id = ta.au_id
Adaptive Server Enterprise
第3章
7>
8>
9>
showplan の使用
and ta.title_id = t.title_id
and a.au_id = t.title_id
and au_lname = "Bloom"
5 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|N-ARY NESTED LOOP JOIN Operator has 3 children.
|
|
|SCAN Operator
|
| FROM TABLE
|
| authors
|
| a
|
| インデックス : aunmind
|
| 前方スキャン
|
| キーによって位置付けます。
|
| キー :
|
|
au_lname ASC
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロバイ
トを使用しています。
|
| インデックス・リーフ・ページに対する LRU でのバッファ置換方式
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用してい
ます。
|
| データ・ページに対する LRU でのバッファ置換方式
|
|
|RESTRICT Operator
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| titleauthor
|
|
| ta
|
|
| インデックス : auidind
|
|
| 前方スキャン
|
|
| キーによって位置付けます。
|
|
| キー :
|
|
|
au_id ASC
|
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロ
バイトを使用しています。
|
|
| インデックス・リーフ・ページに対する LRU でのバッファ置
換方式
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用し
ています。
|
|
| データ・ページに対する LRU でのバッファ置換方式
|
|
|SCAN Operator
|
クエリ・プロセッサ
|
FROM TABLE
121
Lava クエリ・プランの形状
|
|
|
|
|
|
|
|
|
ます。
|
|
|
|
|
|
|
|
|
|
titles
t
クラスタード・インデックスを使用します。
インデックス : titleidind
前方スキャン
キーによって位置付けます。
キー :
title_id ASC
データ・ページに対して I/O サイズ 2 キロバイトを使用してい
|
データ・ページに対する LRU でのバッファ置換方式
この例では、次のツリーに示すように複数のネスト・ループ・ジョインが存在
します。
図 3-3: Lava オペレータ・ツリー
Emit
(VA = 6)
NestLoopJoin
InnerJoin
(VA = 5)
NestLoopJoin
InnerJoin
(VA = 3)
IndexScan
aunmid (a)
(VA = 0)
IndexScan
titleidind (t2)
(VA = 4)
Restrict
(0) (0) (4) (0)
(VA = 2)
IndexScan
auidind (ta)
(VA = 1)
すべての Lava オペレータには仮想アドレス (VA) が割り当てられています。図
の VA= の行は、各オペレータの仮想アドレスを示しています。
効果的なジョインの順序は、authors、titleauthor、titles の順です。Restrict オ
ペレータは titleauthors に対するスキャンの親オペレータです。このプランは、
次に示す Nary Nested Loop Join プランに変形されます。
122
Adaptive Server Enterprise
第3章
showplan の使用
図 3-4: Lava オペレータ NaryNestedLoop
Emit
(VA=5)
NaryNLJoin
(VA = 4)
IndexScan
aunmid (a)
(VA = 0)
NaryNLJoin
(VA = 4)
Restrict
(0) (0) (4) (0)
(VA = 2)
NaryNLJoin
(VA = 4)
IndexScan_______________________________IndexScan
auidind(ta)_________________________________titleidind (t)
(VA = 1)_________________________________(VA = 3)
変形であっても、authors、titleauthor、titles の当初のジョイン順はそのままに
なっています。この例で、titles のスキャンには 2 つの SARG があります。そ
れらは、ta.title_id = t.title_id と a.au_id = t.title_id です。そのため、titles のス
キャンは、titleauthor のスキャンによって確立された SARG 値のために失敗す
るか、authors のスキャンによって確立された SARG 値のために失敗する可能
性があります。authors のスキャンで設定された SARG 値のために titles のス
キャンで戻されるローが何もない場合、titleauthor のスキャンを続行する点が
何もなくなります。titleauthor からフェッチされるそれぞれのローに対する
titles のスキャンは失敗します。titles のスキャンが成功する可能性があるのは、
authors から新しいローがフェッチされる場合のみになります。これこそが、
Nary Nest Loop Join が実装された理由です。Nary Nest Loop Join では、連続す
るスキャンによって返されるローに対して何の影響もないテーブルの不要な
排出を行いません。この例では、Nary Nested Loop Join オペレータは titleauthor
のスキャンをクローズし、authors から新しいローをフェッチして、authors か
らフェッチした au_id に基づいて titleauthor のスキャンの位置付けを再度行い
ます。これによって、titleauthor テーブルの不必要な排出とそれに関連して発
生する I/O がなくなるので、パフォーマンスが大幅に向上します。
クエリ・プロセッサ
123
Lava クエリ・プランの形状
重複削除オペレータ
重複削除を実現するために使用できる Lava オペレータは 3 種類あります。
Group Sorted Distinct、Sort Distinct、および Hash Distinct の各オペレータです。
これらはすべて単項オペレータです。それぞれに長所と短所があります。オプ
ティマイザは、クエリ・プランのコンテキスト全体での用途を考慮して、効率
的な distinct オペレータを選択します。
Group Sorted オペレータ
Group Sorted オペレータは単項オペレータです。重複削除を適用するために使
用できます。入力ストリームが distinct カラムであらかじめソートされている
必要があります。その子オペレータからローを読み込み、現在の distinct カラ
ムの値がフィルタされるように初期化します。ローは親オペレータに返されま
す。Group Sorted オペレータは、別のローをフェッチするためにもう一度呼び
出されたときに、子から別のローをフェッチし、現在のキャッシュ値とその値
を比較します。値が重複している場合、そのローは廃棄され、新しいローを
フェッチするために子がもう一度呼び出されます。このプロセスは、新しい
distinct ローが見つかるまで続行されます。このローの distinct カラムの値は、
キャッシュされ、重複が削除されていないローを削除するために後で使用され
ます。現在のローはさらに処理を行うために親オペレータに返されます。
Group Sorted オペレータはソートされたストリームを返します。ソートされ、
重複を削除したデータ・ストリームを返すことは、オプティマイザがその後の
アップストリーム処理でパフォーマンスを向上させるために活用できるプロ
パティです。Group Sorted オペレータは非ブロック・オペレータです。Group
Sorted オペレータは distinct ローがフェッチされるとその親に即座に返します。
入力ストリーム全体を処理し終わってからローが返し始められるということ
はありません。
1>
2>
3>
4>
-- Collect distinct last and first author names.
select distinct au_lname, au_fname
from authors
where au_lname = "Bloom"
文 1 (2 行目 ) のクエリ・プラン。
2 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|GROUP SORTED Operator
|Distinct
|
|
|SCAN Operator
|
| FROM TABLE
|
| authors
|
| インデックス : aunmind
124
Adaptive Server Enterprise
第3章
showplan の使用
|
| 前方スキャン
|
| キーによって位置付けます。
|
| インデックスは必要なカラムをすべて含んでいます。ベース・テー
ブルは読み込まれません。
|
| キー :
|
|
au_lname ASC
|
| インデックス・リーフ・ページに対して I/O サイズ 2 キロバイ
トを使用しています。
|
| インデックス・リーフ・ページに対する LRU でのバッファ置換方式
Distinct Sorted オペレータは、scan オペレータが distinct カラムである au_lname
および au_fname 用にソートされた順序のローを返しているので、このクエ
リ・プランで distinct プロパティを適用するように選択されました。Group
Sorted オペレータをここで使用すると、I/O はなくなり、CPU オーバヘッドは
最小限になります。
また、Group Sorted オペレータは、ベクトル集合関数を実装するために使用す
ることもできます。詳細については、
「ベクトル集合オペレータ vector aggregate
operator」(127 ページ ) を参照してください。showplan 出力には、この Group
Sorted オペレータが distinct プロパティを実装していることを示す Distinct
行があります。
Sort Distinct オペレータ
Sort Distinct オペレータは単項オペレータです。その入力ストリームがあらか
じめ distinct キー・カラムでソートされている必要はありません。これは、子
オペレータのストリームを排出し、読み込まれるときにローをソートするブ
ロック・オペレータです。distinct ローは、ローのすべてがソートされた後に
親オペレータに返されます。ローは distinct キー・カラムでソートされて返さ
れます。内部ワーク・テーブルは、入力セットがメモリ内に収まりきらない場
合に備えて、補助記憶として使用されます。
1> select distinct au_lname, au_fname
2> from authors
3> where city = "Oakland"
2 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SORT Operator
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|SCAN Operator
|
| FROM TABLE
|
| authors
|
| テーブル・スキャンです。
|
| 前方スキャン
クエリ・プロセッサ
125
Lava クエリ・プランの形状
|
|
ます。
|
|
|
テーブルの最初に位置付けます。
データ・ページに対して I/O サイズ 2 キロバイトを使用してい
|
データ・ページに対する LRU でのバッファ置換方式
authors テーブルのスキャンは distinct キー・カラムでソートされたローは返しま
せん。このため、Group Sorted オペレータよりも Sort Distinct オペレータが使用さ
れることが必要です。sort オペレータの distinct キー・カラムは au_lname と
au_fname です。showplan 出力は、入力セットがメモリ内に収まりきらない場合
に備えて、ワーク・テーブル 1 が補助記憶として使用されることを示します。
Hash Distinct オペレータ
Hash Distinct オペレータは、その入力セットが distinct キー・カラムでソート
されていることを必要としません。これは、非ブロック・オペレータです。
ローは、子オペレータから読み込まれ、distinct キー・カラムでハッシュされ
ます。これによってローが配置されるバケットが決定されます。対応するバ
ケットは、キーがすでに存在するかどうかについて検索されます。ローに重複
するキーがある場合にはそのローは廃棄され、子オペレータから別のローが
フェッチされます。重複する distinct キーがまだ存在せず、ローがさらなる処
理のために親オペレータに渡される場合、ローはバケットに追加されます。
ローは distinct キー・カラムでソートされて返されることはありません。
Hash Distinct オペレータが通常使用されるのは、入力セットが distinct キー・カ
ラムでまたソートされておらず、オプティマイザがプランでの後の重複削除処
理による順序付けを活用できない場合です。
1>
2>
3>
4>
select distinct au_lname, au_fname
from authors a
where city = "Oakland"
go
文 1 (1 行目 ) のクエリ・プラン。
2 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|HASH DISTINCT Operator
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|SCAN Operator
|
| FROM TABLE
|
| authors
|
| a
|
| テーブル・スキャンです。
|
| 前方スキャン
|
| テーブルの最初に位置付けます。
126
Adaptive Server Enterprise
第3章
|
ます。
|
showplan の使用
|
データ・ページに対して I/O サイズ 2 キロバイトを使用してい
|
データ・ページに対する LRU でのバッファ置換方式
この例では、authors テーブル・スキャンの出力はソートされません。オプティ
マイザは、sort distinct 方式または hash distinct 方式のいずれかを選択できま
す。sort distinct 方式で提供される順序付けは、プランの他のどこの場所でも
利用できるわけではないので、オプティマイザは hash distinct 方式を選択する
ものと推測されます。オプティマイザの決定は、最終的にはコスト見積もりに
よって決まります。Hash Distinct オペレータは、現在のローの値を集約して
ローが処理されるときにローの削除を行う機能があるので、通常は比較的コス
トがかかりません。Sort Distinct オペレータは、データ・セット全体がソート
されるまで、ローの削除はできません。
Hash Distinct オペレータの showplan 出力では、ワーク・テーブル 1 が使用され
ることが示されています。ワーク・テーブルは、distinct ロー結果セットがメ
モリ内に収まらない場合には必要になります。その場合、処理されたグループ
が部分的にディスクに書き出されます。
ベクトル集合オペレータ vector aggregate operator
ベクトル集合関数に使用される単項オペレータが 2 つあります。それらは、
Group Sorted オペレータと Hash Vector Aggregate オペレータです。
グループ化集合関数メッセージ
グループ化された type AGGREGATE を評価します。
このメッセージは、group by 集合関数句を含むクエリによって出力されます。
type 変数は、適用される集合関数、count、sum、average、minimum、または
maximum を示しています。
Group Sorted Aggregate オペレータ
Group Sorted Aggregate オペレータは、前述した Group Sorted Distinct オペレー
タの変形です。これは、入力セットが group by カラムでソートされている必
要があります。アルゴリズムは似ています。あるローが子オペレータから読み
込まれます。これが新しいベクトルの開始である場合、そのグループ化カラム
がキャッシュされ、集合関数の結果が初期化されます。ローが現在処理される
グループに属している場合、集合関数は集合関数の結果に適用されます。子オ
ペレータが新しいグループを開始するローまたは End Of Scan を返すと、現在
のベクトルおよびその集合関数の結果が親オペレータに返されます。
これは、Group Sorted オペレータと同じく非ブロック・オペレータですが、異
なる点が 1 つあります。Group Sorted Aggregate オペレータの最初のローはグ
ループ全体が処理された後に返されますが、Group Sorted Distinct オペレータの
場合は、最初のローは新しいグループの開始時に返されます。
クエリ・プロセッサ
127
Lava クエリ・プランの形状
1> -- Collect a list of all cities with the number of authors
that
2> -- live in each city.
3> select city, total_authors = count(*)
4>
from authors
5>
group by city
6> plan
7> "(group_sorted
8>
(sort (scan authors))
9> )"
10> go
文 1 (3 行目 ) のクエリ・プラン。
PLAN 句に Abstract Plan を使用して最適化しました。
3 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|GROUP SORTED Operator
| グループ化された COUNT AGGREGATE を評価します。
|
|
|SORT Operator
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| authors
|
|
| テーブル・スキャンです。
|
|
| 前方スキャン
|
|
| テーブルの最初に位置付けます。
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用し
ています。
|
|
| データ・ページに対する LRU でのバッファ置換方式
このクエリ・プランでは、authors のスキャンはグループ化の順序でローを返
しません。Sort オペレータはグループ化カラム city によってストリームの順序
付けを行うように適用されます。この時点で、count() 集合関数を評価するた
めに Group Sorted Vector Aggregate オペレータを適用できます。
Group Sorted Vector Aggregate オペレータの showplan 出力は、適用される集合
関数の内容を次のように示しています。
|
128
グループ化された COUNT AGGREGATE を評価します。
Adaptive Server Enterprise
第3章
showplan の使用
Hash vector aggregate オペレータ
hash vector aggregate オペレータはブロック・オペレータです。子オペレー
タのすべてのローは、Hash Vector Aggregate オペレータの最初のローが親オペ
レータに返される前に処理される必要があります。この点を除くと、アルゴリ
ズムは Hash Distinct オペレータのアルゴリズムと似ています。
ローは子オペレータからフェッチされます。各ローはクエリのグループ化カラ
ムでハッシュされます。ハッシュされるバケットは、ベクトルがすでに存在す
るかどうかについて検索されます。
group by 値が存在しない場合、ベクトルが追加され、集約値は最初のローを
使用して初期化されます。group by 値が存在する場合は、現在のローが既存
の値に集計されます。
1> -- Collect a list of all cities with the number of authors
that
2> -- live in each city.
3> select city, total_authors = count(*)
4>
from authors
5>
group by city
6> go
文 1 (3 行目 ) のクエリ・プラン。
2 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|HASH VECTOR AGGREGATE Operator
| GROUP BY
| グループ化された COUNT AGGREGATE を評価します。
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|SCAN Operator
|
| FROM TABLE
|
| authors
|
| テーブル・スキャンです。
|
| 前方スキャン
|
| テーブルの最初に位置付けます。
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用してい
ます。
|
| データ・ページに対する LRU でのバッファ置換方式
クエリ・プロセッサ
129
Lava クエリ・プランの形状
このクエリ・プランでは、Hash Vector Aggregate オペレータは子オペレータか
らすべてのローを読み込みます。子オペレータは authors テーブルをスキャン
しています。各ローは、現在の city 値に対してバケット・エントリがすでに存
在するかどうかをチェックされます。存在しない場合、ハッシュ・エントリ・
ローが新しい city グループ化値とともに追加され、カウント結果が 1 に初期化
されます。新しいローの city 値にハッシュ・エントリがすでに存在する場合
は、集合関数が適用されます。この場合、カウント結果は増分されます。
showplan 出力は Hash Vector Aggregate オペレータに対しては "GROUP BY"
メッセージを出力し、次のグループ化集合関数メッセージを出力します。
|
グループ化された COUNT AGGREGATE を評価します。
次に、showplan 出力は、ディスクに書き出されるグループと未処理のローを格
納するためにどのワーク・テーブルが使用されるのかをレポートします。
| ワーク・テーブル 1 を内部記憶に使用しています。
compute by メッセージ
“compute by” 処理は、Emit オペレータで行われます。compute by では、Emit オ
ペレータの入力ストリームがクエリのいずれかの order by 要求に従ってソー
トされている必要があります。処理は Group Sorted Aggregate オペレータで行
われる内容と似ています。子から読み込まれる各ローは、新しいグループを開
始するかどうかをチェックされます。新しいグループを開始しない場合、集合
関数がクエリから要求されるグループに妥当なかたちで適用されます。新しい
グループを開始する場合は、新しいグループまたは新しいグループの集約値が
新しいローの値から再度初期化されます。
1> -- Collect an ordered list of all cities and report a count
of the
2> -- number of entries for each city after the city's list is
finished.
3> select city
4>
from authors
5>
order by city
6>
compute count(city) by city
7> go
文 1 (3 行目 ) のクエリ・プラン。
2 operator(s) under root
クエリのタイプは SELECT です。
Emit with Compute semantics
ROOT:EMIT Operator
|SORT Operator
| ワーク・テーブル 1 を内部記憶に使用しています。
|
130
Adaptive Server Enterprise
第3章
|
|
|
|
|
|
|
ます。
|
showplan の使用
|SCAN Operator
| FROM TABLE
| authors
| テーブル・スキャンです。
| 前方スキャン
| テーブルの最初に位置付けます。
| データ・ページに対して I/O サイズ 2 キロバイトを使用してい
|
データ・ページに対する LRU でのバッファ置換方式
この例で、Emit オペレータの入力ストリームは city 属性でソートされます。各
ローに対して compute by のカウント値が増分されます。新しい city 値がフェッ
チされると、前の city の値のカウントがユーザに返されて新しい city のカウン
トが 1 に再初期化され、新しい city の値が新しい compute by のグループ化値
としてキャッシュされます。
和集合オペレータ
hash union
hash union オペレータは、複数のデータ・ストリームに対する union all 演算
とハッシュベースの重複削除を同時に行うために、Adaptive Server 15.0 のハッ
シュ・アルゴリズムを使用しています。
hash union オペレータは n 項オペレータです。次のメッセージが表示されます。
HASH UNION OPERATOR has <N> children.
N は、オペレータに対する入力ストリームの数です。
また、次のフォーマットで使用するワーク・テーブルの名前も表示します。
HASH UNION OPERATOR ワーク・テーブル <X> を内部記憶に使用しています。
ここでは、hash union の使用例を示します。
例
select * from sysindexes
union
select * from sysindexes
文 1 (8 行目 ) のクエリ・プラン。
調整プロセスと 2 作業プロセスにより並列に実行されました。
6 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
クエリ・プロセッサ
131
和集合オペレータ
|SORT Operator
| ワーク・テーブル 2 を内部記憶に使用しています。
|
|
|EXCHANGE Operator
|
| Executed in parallel by 2 Producer and 1 Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|HASH UNION Operator has 2 children.
|
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|SCAN Operator
|
|
| FROM TABLE
|
|
| sysindexes
|
|
| テーブル・スキャンです。
|
|
| 前方スキャン
|
|
| テーブルの最初に位置付けます。
|
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
|
|
| データ・ページに対する LRU でのバッファ置換
|
|
|
方式
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|SCAN Operator
| FROM TABLE
| sysindexes
| テーブル・スキャンです。
| 前方スキャン
| テーブルの最初に位置付けます。
| データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
| データ・ページに対する LRU でのバッファ置換
|
方式
merge union
merge union オペレータは、複数の互換性のあるソートされたデータ・スト
リームに対して union all 演算を実行し、これらのストリーム内の重複を削除
します。
merge union オペレータは n 項オペレータです。次のメッセージが表示されます。
MERGE UNION OPERATOR has <N> children.
N は、オペレータに対する入力ストリームの数です。
132
Adaptive Server Enterprise
第3章
showplan の使用
union all オペレータ
union all オペレータは、重複の削除を実行することなく複数の互換性のある入
力ストリームをマージします。union all オペレータに入るすべてのデータ・
ローは、オペレータの出力ストリームに含まれます。
union all オペレータは n 項オペレータです。次のメッセージが表示されます。
UNION ALL OPERATOR
has N children.
N は、オペレータに対する入力ストリームの数です。
ここでは、union all の使用例を示します。
例
select * from sysindexes
union all
select * from sysindexes
文 1 (4 行目 ) のクエリ・プラン。
調整プロセスと 3 作業プロセスにより並列に実行されました。
6 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SORT Operator
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|UNION ALL Operator has 2 children.
|
|
|
|
|EXCHANGE Operator
|
|
|Executed in parallel by 3 Producer and 1 Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
クエリ・プロセッサ
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:Emit Operator
|
|
|SCAN Operator
|
| FROM TABLE
|
| sysindexes
|
| テーブル・スキャンです。
|
| 前方スキャン
|
| Positioning at start of table.
|
| データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
|
| データ・ページに対する LRU でのバッファ置換
|
|
方式
|SCAN Operator
| FROM TABLE
| sysindexes
| テーブル・スキャンです。
| 前方スキャン
133
和集合オペレータ
|
|
|
|
|
|
|
|
|
テーブルの最初に位置付けます。
データ・ページに対して I/O サイズ 2 キロバイトを使用しています。
データ・ページに対する LRU でのバッファ置換方式
scalaragg オペレータ
scalar aggregate オペレータは、ストリーム内のローの数、ストリーム内の特
定カラムの最大値など、入力データ・ストリームに関する現在の情報を追跡し
ます。
scalar aggregate オペレータは、実行するスカラ集合関数を説明する最大 10 個
のメッセージ・リストを出力します。メッセージのフォーマットは次のとおり
です。
グループ化されていない <Type of the Aggragate> AGGREGATE を評価します。
type of aggregate には、count、sum、average、min、max、any、once-unique、
count-unique、sum-unique、average-unique、または once を指定できます。
次のクエリは、データベース pubs2 の authors テーブルに対してスカラ ( グルー
プ化されていない ) 集合関数を実行します。
1>
2>
1>
2>
1>
2>
use pubs2
go
set showplan on
go
select count(*) from authors
go
文 1 (1 行目 ) のクエリ・プラン。
2 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SCALAR AGGREGATE Operator
| グループ化されていない COUNT AGGREGATE を評価します。
|
|
|SCAN Operator
|
| FROM TABLE
|
| authors
|
| インデックス : aunmind
|
| 前方スキャン
|
| インデックスの最初に位置付けます。
|
| インデックスは必要なカラムをすべて含んでいます。ベース・テー
ブルは読み込まれません。
|
| インデックス・リーフ・ページに対して I/O サイズ 4 キロバイ
トを使用しています。
134
Adaptive Server Enterprise
第3章
|
|
showplan の使用
インデックス・リーフ・ページに対する LRU でのバッファ置換方式
----------23
(1 row affected)
scalar aggregate オペレータに関連して表示されるメッセージは、クエリがグルー
プ化されていない count aggregate に対して実行されることを示しています。
restrict オペレータ
restrict オペレータは、カラム値を基にして式を評価します。restrict オペレー
タは、子オペレータからローをフェッチする前、子オペレータからローを
フェッチした後、または子オペレータからローをフェッチした後の仮想カラム
の値を計算するために処理できる複数のカラム評価リストに関連しています。
sort オペレータ
sort オペレータは、クエリ・プラン内で 1 つの子オペレータのみを持ちます。
その役割は、指定されたソート・キーを使用して入力ストリームから出力デー
タ・ストリームを生成することです。
sort オペレータは、可能な場合にはストリーミング・ソートを実行しますが、
結果を一時的にワーク・テーブルに格納することが必要な場合もあります。
ワーク・テーブルを使用する場合、sort オペレータはワーク・テーブルの名前
を次のフォーマットで示します。
ワーク・テーブル <N> を内部記憶に使用しています。
N は、showplan 出力内のワーク・テーブルの数値識別子です。
次に示すのは、sort オペレータとワーク・テーブルを使用した簡単なクエリ・
プランの例です。
1>
2>
1>
2>
1>
2>
use pubs2
go
set showplan on
go
select au_id from authors order by postalcode
go
文 1 (1 行目 ) のクエリ・プラン。
2 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
クエリ・プロセッサ
135
和集合オペレータ
|SORT Operator
| ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|SCAN Operator
|
| FROM TABLE
|
| authors
|
| テーブル・スキャンです。
|
| 前方スキャン
|
| テーブルの最初に位置付けます。
|
| データ・ページに対して I/O サイズ 4 キロバイトを使用しています。
|
| データ・ページに対する LRU でのバッファ置換方式
au_id
---------------------807-91-6654
527-72-3246
722-51-5454
712-45-1867
341-22-1782
899-46-2035
998-72-3567
172-32-1176
486-29-1786
427-17-2319
846-92-7186
672-71-3249
274-80-9391
724-08-9931
756-30-7391
724-80-9391
213-46-8915
238-95-7766
409-56-7008
267-41-2394
472-27-2349
893-72-1158
648-92-1872
(23 個のローが影響を受けます )
136
Adaptive Server Enterprise
第3章
showplan の使用
store オペレータ
store オペレータは、ワーク・テーブルの作成、値の格納、可能な場合のイン
デックスの設定をクエリ・プランの実行の一環として行うために使用されます。
ワーク・テーブルは、プラン内の他のオペレータで使用されます。SEQUENCER
オペレータは、ワーク・テーブルに対応するプラン・フラグメントと可能な場
合のインデックスの作成が、ワーク・テーブルを利用する他のプラン・フラグ
メントよりも前に実行されることを保証します。これは、実行処理が非同期で
動作するので、プランが並列で実行されるときには特に重要です。
再フォーマット・プランでは、特にこのオペレータを使用してワーク・テーブ
ルの作成とワーク・テーブルのインデックスの作成が行われます。
store オペレータが再フォーマット・オペレーションに使用される場合、次の
メッセージが出力されます。
ワーク・テーブル <X> が ロック・モード <L> で REFORMATTING に対して作
成されました。
ロック・モード L は、“allpages”、“datapages”、“datarows” のいずれかである必
要があります。
また、次のメッセージも表示されます。
Creating clustered index.
store オペレータが再フォーマット・オペレーションに使用されない場合、次
のメッセージが出力されます。
ワーク・テーブル <X> がロック・モード <L> で作成されました。
ロック・モード L は、"allpages"、"datapages"、"datarows" のいずれかである必
要があります。
次の例は、store オペレータとともに、次の項で説明する sequencer オペレー
タで使用されます。
1> use master
2> go
1> set showplan on
2> go
1> select * from sysindexes S1, sysobjects S2
2> where S1.id = S2.id
文 1 (1 行目 ) のクエリ・プラン。
PLAN 句に Abstract Plan を使用して最適化しました。
調整プロセスと 42 作業プロセスにより並列に実行されました。
15 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SEQUENCER Operator has 2 children.
|
クエリ・プロセッサ
137
和集合オペレータ
|
|EXCHANGE Operator
|
|Executed in parallel by 20 Producer and 1 Consumer
processes.
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|STORE Operator
|
|
|
| ワーク・テーブル 1 が ロック・モード allpages で
REFORMATTING に対して作成されました。
|
|
|
| Creating clustered index.
|
|
|
|
|
|
|
|
|INSERT Operator
|
|
|
|
| 直接更新モードです。
|
|
|
|
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|
|
|Executed in parallel by 1 Producer and
20 Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
|
|
|
| FROM TABLE
|
|
|
|
|
|
|
| sysobjects
|
|
|
|
|
|
|
| S2
|
|
|
|
|
|
|
| クラスタード・インデックスを使用
します。
|
|
|
|
|
|
|
| インデックス : csysobjects
|
|
|
|
|
|
|
| 前方スキャン
|
|
|
|
|
|
|
| インデックスの最初に位置付けます。
|
|
|
|
|
|
|
| インデックス・リーフ・ページに対
して I/O サイズ 4 キロバイトを使用しています。
|
|
|
|
|
|
|
| インデックス・リーフ・ページに対
する LRU でのバッファ置換方式
|
|
|
|
|
|
|
| データ・ページに対して I/O サイ
ズ 4 キロバイトを使用しています。
|
|
|
|
|
|
|
| データ・ページに対する LRU での
バッファ置換方式
|
|
|
|
|
|
|
|
|
| TO TABLE
|
|
|
|
| ワーク・テーブル 1
|
|
|EXCHANGE Operator
|
|Executed in parallel by 20 Producer and 1 Consumer
processes.
|
|
138
|
|
|EXCHANGE:EMIT Operator
Adaptive Server Enterprise
第3章
showplan の使用
|
|
|
|
|
|
|NESTED LOOP Operator (Join Type: Inner Join)
|
|
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|
|Executed in parallel by 1 Producer and 20
Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|SCAN Operator
|
| FROM TABLE
|
| sysindexes
|
| S1
|
| クラスタード・インデックスを使用します。
|
| インデックス : csysindexes
|
| 前方スキャン
前述のプランでは、見やすくするために store オペレータが強調表示されていま
す。このプランでは、store オペレータは、sequencer ノードの下で、sequencer
の左側の子プラン内の位置にあります。store オペレータの親オペレータは
emit:exchange オペレータで、その子オペレータは insert オペレータです。
exchange オペレータの下にあるプラン・フラグメントに位置しており、
exchange
オペレータで示されるように 20 ワーカー・プロセスで並列に実行されます。
store オペレータはワーク・テーブルを作成します。このワーク・テーブルは
その下にある insert オペレータから値が格納されます。次に、store オペレー
タはワーク・テーブルにクラスタード・インデックスを作成します。クラス
タード・インデックスはネスト・ループ・ジョイン・キーに対して構築されま
す。store オペレータで作成されるワーク・テーブルの名前は、この場合はワー
ク・テーブル 1 です。
sequencer オペレータ
sequencer オペレータは n 項オペレータであり、その下にある子プランを 1 つ
ずつ順番に実行するために使用されます。これは、特に reformatting プランと、
一定の集合関数処理プランで使用されます。
sequencer オペレータは、右端の子サブプランを除く、子サブプランそれぞれ
を実行します。左側の子サブプランすべてを実行した後、右端のサブプランを
実行します。
sequencer オペレータは次のメッセージを表示します。
SEQUENCER operator has N children.
ここでもう一度、前の項の store オペレータを見てみましょう。
ROOT:EMIT Operator
|SEQUENCER Operator has 2 children.
クエリ・プロセッサ
139
和集合オペレータ
|
|
|EXCHANGE Operator
|
|Executed in parallel by 20 Producer and 1 Consumer
processes.
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|STORE Operator
|
|
|
| ワーク・テーブル 1 が ロック・モード allpages で
REFORMATTING に対して作成されました。
|
|
|
| Creating clustered index.
|
|
|
|
|
|
|
|
|INSERT Operator
|
|
|
|
| 直接更新モードです。
|
|
|
|
|
|
|
|
|
|
|EXCHANGE Operator
|
|
| | | |Executed in parallel by 1 Producer and
20 Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|SCAN Operator
|
|
|
|
|
|
|
| FROM TABLE
|
|
|
|
|
|
|
| sysobjects
|
|
|
|
|
|
|
| S2
|
|
|
|
|
|
|
| クラスタード・インデックスを使用
します。
|
|
|
|
|
|
|
| インデックス : csysobjects
|
|
|
|
|
|
|
| 前方スキャン
|
|
|
|
|
|
|
| インデックスの最初に位置付けます。
|
|
|
|
|
|
|
| インデックス・リーフ・ページに対
して I/O サイズ 4 キロバイトを使用しています。
|
|
|
|
|
|
|
| インデックス・リーフ・ページに対
する LRU でのバッファ置換方式
|
|
|
|
|
|
|
| データ・ページに対して I/O サイ
ズ 4 キロバイトを使用しています。
|
|
|
|
|
|
|
| データ・ページに対する LRU での
バッファ置換方式
|
|
|
|
|
|
|
|
|
| TO TABLE
|
|
|
|
| ワーク・テーブル 1
|
|
|EXCHANGE Operator
|
|Executed in parallel by 20 Producer and 1 Consumer
processes.
|
|
|
140
|
|
|
|EXCHANGE:EMIT Operator
|
Adaptive Server Enterprise
第3章
showplan の使用
|
|
|
|NESTED LOOP Operator (Join Type: Inner Join)
|
|
|
|
|
|
|
|
|EXCHANGE Operator
|
|
|
|
|Executed in parallel by 1 Producer and 20
Consumer processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|SCAN Operator
|
| FROM TABLE
|
| sysindexes
|
| S1
|
| クラスタード・インデックスを使用します。
|
| インデックス : csysindexes
|
| 前方スキャン
ここでは、プラン内の sequencer オペレータを強調表示しています。sequencer
オペレータには 2 つの子オペレータがあることがわかります。左端のサブプラ
ンは、再フォーマットに使用されるワーク・テーブルを作成し、右端のサブプ
ランはこのワーク・テーブルを使用してシステム・テーブル sysindexes とのネス
ト・ループ・ジョインを発生させます。この例では、テーブルの作成/インデッ
クスの作成とネストループ・ジョイン・オペレーションが並列で実行されるこ
とに注意してください。
remscan オペレータ
remote scan オペレータは、実行のために SQL クエリをリモート・サーバに
送信します。リモート・サーバから戻される結果があれば、それを処理しま
す。remote scan オペレータは、取り扱う SQL クエリのフォーマットされた
テキストを表示します。
remote scan オペレータには 0 または 1 つの子オペレータがあります。
scroll オペレータ
scroll オペレータは、ASE でスクロール可能カーソルの機能をカプセル化しま
す。スクロール可能カーソルは非反映型である可能性があります。非反映型と
は、スクロール可能カーソルがオープン・カーソル時に取られた関連データの
スナップショットを表示することです。あるいは、半反映型である可能性もあ
ります。半反映型とは、フェッチされる次のローがスナップショットからでは
なくライブ・データから取得されることです。
scroll オペレータは単項オペレータです。
scroll オペレータは次のメッセージを表示します。
SCROLL OPERATOR ( Sensitive Type: <T>)
クエリ・プロセッサ
141
和集合オペレータ
タイプは、"Insensitive" または "Semi-Sensitive" のいずれかになります。
次の例は、非反映型スクロール可能カーソルを含むプランです。
1>
2>
1>
2>
3>
1>
2>
1>
2>
use pubs2
go
declare CI insensitive scroll cursor for
select au_lname, au_id from authors
go
set showplan on
go
open CI
go
文 1 (1 行目 ) のクエリ・プラン。
STEP 1
クエリのタイプは OPEN CURSOR CI です。
文 1 (2 行目 ) のクエリ・プラン。
2 operator(s) under root
クエリのタイプは DECLARE CURSOR です。
ROOT:EMIT Operator
|SCROLL Operator (Sensitive Type: Insensitive)
|
ワーク・テーブル 1 を内部記憶に使用しています。
|
|
|SCAN Operator
|
| FROM TABLE
|
| authors
|
| テーブル・スキャンです。
|
| 前方スキャン
|
| テーブルの最初に位置付けます。
|
| データ・ページに対して I/O サイズ 4 キロバイトを使用してい
ます。
|
| データ・ページに対する LRU でのバッファ置換方式
scroll オペレータはルートの emit オペレータの子オペレータであり、その唯一
の子が authors テーブルの scan オペレータです。scroll オペレータのメッセー
ジは、カーソル CI が非反映型であることを示しています。
142
Adaptive Server Enterprise
第3章
showplan の使用
ridjoin オペレータ
rid join オペレータは、同じソース・テーブルからの 2 つのデータ・ストリー
ムのロー ID によるジョインを発生させます。rid join オペレータは 2 項オペ
レータです。
SQL テーブルの各データ・ローは、ユニークなロー ID (rid) に関連付けられて
います。rid join はセルフジョイン・クエリに使用されます。左側の子は、ソー
ス・テーブルのインデックス・スキャンの結果、条件を満たす RID でワーク・
テーブルに値を格納します。次に、このワーク・テーブルが、左側の子による
同じソース・テーブルの別のインデックス・スキャンで返された RID とジョ
インされます。最後の手順は、結果の RID と関連付けられたデータ・ローを
取得することです。
RID JOIN オペレータは次のメッセージを表示します。
ワーク・テーブル <X> を内部記憶に使用しています。
sqfilter オペレータ
sqfilter は、サブクエリの実行のために使用されます。その左端の子は外部ク
エリを表し、残りの子は 1 つ以上のサブクエリに関連付けられたクエリ・プラ
ン・フラグメントを表します。sqfilterop オペレータは n 項オペレータです。
左端の子は、残りの子プランに代入予定の相関値を生成します。
SQFILTER オペレータは次のメッセージを表示します。
SQFILTER Operator has <N> children.
ここでは sqfilter の使用例を示します。
例
select pub_name from publishers
where pub_id =
(select distinct titles.pub_id from titles
where publishers.pub_id = titles.pub_id
and price > $1000)
文 1 (1 行目 ) のクエリ・プラン。
4 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SQFILTER Operator has 2 children.
|
| |SCAN Operator
| | FROM TABLE
| | publishers
| | テーブル・スキャンです。
| | 前方スキャン
| | テーブルの最初に位置付けます。
クエリ・プロセッサ
143
和集合オペレータ
| | データ・ページに対して I/O サイズ 8 キロバイトを使用しています。
| | データ・ページに対する LRU でのバッファ置換方式
|
| サブクエリ 1 の実行 ( ネスト・レベル 1)
|
| サブクエリ 1 に対するクエリ・プラン ( ネスト・レベル 1、3 行目 )
|
| 相関サブクエリ
| EXPRESSION 述語内のサブクエリ。
|
| |SCALAR AGGREGATE Operator
| | グループ化されていない ONCE-UNIQUE AGGREGATE を評価します。
| |
| | |SCAN Operator
| | | FROM TABLE
| | | titles
| | | テーブル・スキャンです。
| | | 前方スキャン
| | | テーブルの最初に位置付けます。
| | | データ・ページに対して I/O サイズ 8 キロバイトを使用しています。
| | | データ・ページに対する LRU でのバッファ置換方式
|
| サブクエリ 1 に対するクエリ・プラン終了
exchange オペレータ
exchange オペレータは、SQL クエリの並列処理をカプセル化します。このオ
ペレータはクエリ・プランのほぼどのような場所にも配置できます。exchange
オペレータは、プランをプラン・フラグメントに分けます。プラン・フラグメ
ントとは、プランのルート・オペレータによって区切られる最大サブプラン、
exchange オペレータとリーフ・ノード ( 通常はスキャン・ノード ) です。
exchange オペレータは単項オペレータです。exchange オペレータの子オペ
レータは exchange:emit オペレータです。exchange オペレータのすぐ下にあ
る exchange:emit オペレータは、exchange オペレータの下にあるプラン・フ
ラグメントのルート・オペレータです。このプラン・フラグメントは、exchange
オペレータに関連付けられたワーカー・プロセスによって実行されます。
exchange オペレータは、exchange オペレータの下に位置するプラン・フラ
グメントを並列実行するワーカー・プロセスを管理します。また、プロセス間
のデータ交換も管理します。
exchange オペレータは、ローカル実行コーディネータとして機能するサーバ・
プロセスと関連付けられています。このプロセスを、exchange オペレータに
関連付けられたベータ・プロセスと呼びます。ベータ・プロセスは、ユーザ接
続に関連付けられたプロセスになることも、ワーカー・プロセスになることも
できます。
144
Adaptive Server Enterprise
第3章
showplan の使用
exchange オペレータは次のメッセージを表示します。
Executed in parallel by N producer and P consumer processes.
プロデューサ・プロセスの数とは exchange オペレータの下にあるプラン・フ
ラグメントを実行するワーカー・プロセスの数のことであり、コンシューマ・
プロセスの数とは、exchange オペレータが含まれているプラン・フラグメン
トを実行するワーカー・プロセスの数のことです。
次の簡単な例を見てみましょう。これは、master データベースにあるシステ
ム・テーブル sysmessages に対する並列クエリの例です。
1>
2>
1>
2>
1>
2>
use master
go
set showplan on
go
select count(*) from sysmessages (parallel 4)
go
文 1 (1 行目 ) のクエリ・プラン。
強制オプション ( 内部で生成された Abstract Plan) を使って最適化しました。
調整プロセスと 4 作業プロセスにより並列に実行されました。
4 operator(s) under root
クエリのタイプは SELECT です。
ROOT:EMIT Operator
|SCALAR AGGREGATE Operator
| グループ化されていない COUNT AGGREGATE を評価します。
|
|
|EXCHANGE Operator
|
|Executed in parallel by 4 Producer and 1 Consumer
processes.
|
|
|
|
|EXCHANGE:EMIT Operator
|
|
|
|
|
|
|SCAN Operator
|
|
|
| FROM TABLE
|
|
|
| sysmessages
|
|
|
| テーブル・スキャンです。
|
|
|
| 前方スキャン
|
|
|
| テーブルの最初に位置付けます。
|
|
|
| 4 方向ハッシュ・スキャンにより並列に実行されました。
|
|
|
| データ・ページに対して I/O サイズ 4 キロバイトを使
用しています。
|
|
|
| データ・ページに対する LRU でのバッファ置換方式
クエリ・プロセッサ
145
和集合オペレータ
----------7597
(1
row affected)
ルート emit オペレータの唯一の子は、ベース・テーブルのロー数のカウント
を計算するために使用される scalar aggregate オペレータであることがわか
ります。
scalar aggregate オペレータの唯一の子オペレータは exchange オペレータです。
この exchange オペレータには 1 つのコンシューマ・プロセスがあります。
このコンシューマ・プロセスはユーザ接続および 4 つのワーカー・プロセス
と関連付けられたプロセスです。これらのそれぞれのワーカー・プロセスは、
並列で同一のプラン・フラグメントを実行します。このプラン・フラグメン
トは exchange:emit オペレータとその下にある scan オペレータで構成され
ています。
データ・ローはワーカー・プロセスからベータ・プロセスとも呼ばれるユー
ザ・プロセスに送信されます。
146
Adaptive Server Enterprise
第
4
章
クエリ最適化方式と見積もりの表示
この章では、クエリ最適化のために設計された set コマンドで出力される
メッセージについて説明します。
トピック名
テキスト・フォーマット・メッセージの set コマンド
ページ
147
XML フォーマット・メッセージの set コマンド
148
使用例
151
set コマンドのパーミッション
153
廃止になったトレース・コマンド
153
テキスト・フォーマット・メッセージの set コマンド
次に示す set コマンドは、診断出力をテキスト・フォーマットで生成しま
す。各モジュール個別のレベルを表示する単一のコマンドである set
option show を使用する構文を示します。
表 4-1: テキスト・フォーマット・メッセージのオプティマイザ設定コマンド
コマンド
モジュール
set option show <normal/brief/long/on/off>
すべてのモジュールに共通の基本構文
set option show_lop <normal/brief/long/on/off>
使用された論理演算子 ( スキャン、ジョインなど ) を表示
する
set option show_managers
<normal/brief/long/on/off>
最適化で使用されたデータ構造マネージャを表示する
set option show_log_props
<normal/brief/long/on/off>
評価された論理プロパティ ( ロー・カウント、選択性など )
を表示する
set option show_parallel
<normal/brief/long/on/off>
並列クエリの最適化に関する詳細な情報を表示する
set option show_histograms
<normal/brief/long/on/off>
探索引数/ジョイン・カラムに関連付けられたヒストグラ
ムの処理を表示する
set option show_abstract_plan
<normal/brief/long/on/off>
抽象プランに関する詳細な情報を表示する
set option show_search_engine
<normal/brief/long/on/off>
ジョイン順を決定するアルゴリズムの詳細を表示する
set option show_counters
<normal/brief/long/on/off>
最適化カウンタを表示する
set option show_best_plan
<normal/brief/long/on/off>
オプティマイザで選択された最適なクエリ・プランの詳細
を表示する
クエリ・プロセッサ
147
XML フォーマット・メッセージの set コマンド
コマンド
モジュール
set option show_pio_costing
<normal/brief/long/on/off>
物理入出力 ( ディスク読み込みと書き込み ) の見積もりを
表示する
set option show_lio_costing
<normal/brief/long/on/off>
論理入出力 ( メモリ読み込みと書き込み ) の見積もりを表
示する
set option show_elimination
<normal/brief/long/on/off>
パーティション削除を表示する
set option show_missing_stats
<normal/brief/long/on/off>
検索引数/ジョイン・カラムから欠落した有用な統計の詳
細を表示する
XML フォーマット・メッセージの set コマンド
Adaptive Server 15.0 では、診断情報を XML ドキュメントで出力できるように、
診断情報が強化されています。これによって、フロント・エンド・ツールで
XML ドキュメントを解釈することがさらに簡単になりました。場合によって
は、Adaptive Server 内のネイティブ XPath クエリ・プロセッサを使用している
ユーザがこの出力に対してクエリを実行できます。
診断出力は、クエリ・オプティマイザまたはクエリ実行レイヤから提供されま
す。診断出力用の XML ドキュメントを生成するには、次の set plan コマンド
を使用します。
set plan for
{show_exec_xml, show_opt_xml, show_execio_xml,
show_lop_xml, show_managers_xml, show_log_props_xml,
show_parallel_xml, show_histograms_xml,
show_abstract_plan_xml, show_search_engine_xml,
show_counters_xml, show_best_plan_xml, show_pio_costing_xml,
show_lio_costing_xml, show_elimination_xml}
to {client | message} on
使用頻度が多いのは最初の 3 つのコマンドですが、他の低レベルのコマンドも
用意されています。
148
コマンド
show_exec_xml
定義
show_execio_xml
I/O の見積もり値と実測値を含めてプラ
ンの出力を取得する。クエリ・テキスト
も含まれる。
show_opt_xml
診断出力を取得する。この出力には、論
理演算子、マネージャからの出力、検索
エンジン診断、最適なクエリ・プランな
ど、すべてのコンポーネントに関する情
報が含まれる。
show_lop_xml
出力の論理演算子ツリーを XML フォー
マットで取得する。
コンパイル済みのプランの出力を XML
フォーマットで取得し、各クエリ・プラ
ンのオペレータを表示する。
Adaptive Server Enterprise
第4章
クエリ最適化方式と見積もりの表示
コマンド
show_managers_xml
定義
show_log_props_xml
特定の同等クラス (クエリ内の 1 つ以上の
関係のグループ ) の論理プロパティを表
示する。
show_parallel_xml
並列クエリ・プラン生成中のオプティマ
イザに関連する診断を表示する。
show_histograms_xml
ヒストグラムおよびヒストグラムのマー
ジに関連する診断を表示する。
show_abstract_plan_xml
抽象プラン生成/アプリケーションを表
示する。
クエリ・オプティマイザの準備フェーズ
に使用された複数のコンポーネント・マ
ネージャの出力を表示する。
show_search_engine_xml
診断に関連する検索エンジンを表示する。
show_counters_xml
プラン・オブジェクト作成/破棄カウン
タを表示する。
show_best_plan_xml
最適なプランを XML フォーマットで表
示する。
show_pio_costing_xml
実 PIO コストを XML フォーマットで表
示する。
show_lio_costing_xml
実 LIO コストを XML フォーマットで表
示する。
show_elimination_xml
パーティション削除を XML フォーマッ
トで表示する。
client
指定すると、出力はクライアントに送ら
れる。
message
指定すると、出力は内部メッセージ・バッ
ファに送られる。
オプションをオフに設定するには、次のように指定します。
set plan for
{show_exec_xml, show_opt_xml, show_execio_xml, show_lop_xml,
show_managers_xml, show_log_props_xml, show_parallel_xml,
show_histograms_xml, show_abstract_plan_xml,
show_search_engine_xml,
show_counters_xml, show_best_plan_xml, show_pio_costing_xml,
show_lio_costing_xml, show_elimination_xml} off
オプションをオフにするときには、送信先ストリームを指定する必要がないこ
とに注意してください。
message を指定した場合、クライアント・アプリケーションで
showplan_in_xml([query_num]) という組み込み関数を使用してバッファから
診断情報を取得する必要があります。
クエリ・プロセッサ
149
XML フォーマット・メッセージの set コマンド
現在、20 個を超えるクエリをバッファにキャッシュできないため、クエリ番
号を識別する有効な値は 0 から 19 までの間になります。キャッシュ内のクエ
リが 20 個になると、キャッシュはクエリ・プランの収集を停止し、残りのク
エリ・プランを無視します。ただし、メッセージ・バッファには引き続きクエ
リ・プランが収集されます。20 個を超えると、取得できるメッセージ・バッ
ファは、値 0 を指定することによるバッファの全体のみになります。
-1 の値を指定すると、キャッシュ内の最後の XML ドキュメントを指定するこ
とになります。
0 の値は、メッセージ・バッファ全体のことです。
メッセージ・バッファはオーバフローする可能性があります。オーバフローが
発生した場合、XML ドキュメントすべてのログを取る方法がなくなるので、
結果としてログは一部になり、それによって無効な XML ドキュメントになり
ます。
showplan_in_xml を使用してメッセージ・バッファをアクセスすると、メッ
セージ・バッファは実行後に破棄されます。
XML ドキュメントはテキスト・カラムとして出力され、十分なサイズではな
い場合はトランケートされるので、テキスト・サイズは最大に設定します。次
のコマンドを使用してテキスト・サイズを 100000 バイトに設定します。
set textsize 100000
set plan が off を指定して発行されると、トレース・オプションすべてがオフ
になっている場合にはすべての XML トレースはオフになります。それ以外の
場合は、指定されたオプションのみがオフになります。指定されていないオプ
ションは引き続き有効であり、トレースは指定された送信先ストリームに対し
て続行されます。新たに set plan オプションを発行すると、以前のオプション
と現在のオプションは結合されますが、送信先ストリームは無条件に新しいス
トリームに切り替えられます。
150
Adaptive Server Enterprise
第4章
クエリ最適化方式と見積もりの表示
使用例
シナリオ A
クライアントへの実行プランの XML プランをトレース出力として取得するに
は、次を使用します。
set plan for show_exec_xml
go
to client on
次に、プランが必要なクエリを実行します。
select id from sysindexes where id < 0
ここで XML ドキュメントが表示されます。
set plan for show_exec_xml off
シナリオ B
実行プランを取得するには、組み込みの showplan_in_xml を使用します。最
後のクエリの出力、あるいはバッチ内またはストアド・プロシージャ内の最初
の 20 クエリからの出力を取得できますが、それ以上は取得できません。
set plan for show_opt_xml to
message on
クエリを次のように実行します。
select id from sysindexes where id < 0
select name from sysobjects where id > 0
go
select showplan_in_xml(0)
go
例では、テキスト・ストリームとして 2 つの XML ドキュメントを取得できま
す。Adaptive Server で XML オプションが有効になっていれば、この組み込み
に対して XPath クエリを実行することができます。
select xmlextract("/", showplan_in_xml(-1))
go
これによって XPath クエリ "/" を最後のクエリによって作成された XML ド
キュメントに対して実行することができます。
シナリオ C
複数のオプションをオンにするには次のように指定します。
set plan for show_exec_xml, show_opt_xml to client on
go
select name from sysobjects where id > 0
go
これによって、オプティマイザとクエリ実行エンジンからの出力が設定され
て、通常のトレースと同様に結果がクライアントに送信されます。
set plan for show_exec_xml off
go
select name from sysobjects where id > 0
go
クエリ・プロセッサ
151
XML フォーマット・メッセージの set コマンド
オプティマイザの診断は、show_opt_xml がオンのままになっているのであれ
ば、引き続き可能です。
シナリオ D
1 つのバッチで一連のクエリを実行するときに、最後のクエリのオプティマイ
ザ・プランを要求できます。これは以前は問題でしたが、現在では解決してい
ます。
set plan for show_opt_xml to message on
go
declare @v int
select @v = 1
select name from sysobjects where id = @v
go
select showplan_in_xml(-1)
go
また、showplan_in_xml() は、同一のバッチの一部になることができます。つ
まり、同じように動作します。showplan_in_xml() 組み込み用のメッセージの
ロギングを無視するには特別な注意を払う必要があります。
ストアド・プロシージャの場合も非常に似た動作になります。プロシージャを
作成するには、次のように指定します。
create proc PP as
declare @v int
select @v = 1
select name from sysobjects where id = @v
go
exec P
go
select showplan_in_xml(-1)
go
ストアド・プロシージャによって別のストアド・プロシージャが呼び出され、
その呼び出されたストアド・プロシージャがコンパイルされ、オプティマイザ
診断がオンになる場合、新しい一連の文のためのオプティマイザ診断も同様に
取得します。show_execio_xml がオンになっており、呼び出されたストアド・
プロシージャのみが実行された場合も同じことが起こります。
シナリオ E
XML ドキュメントである、クエリ実行プラン用の showplan_in_xml() の出力
を問い合わせる場合は、次のようになります。
set plan for show_exec_xml to message on
go
select name from sysobjects
go
select case when
'/Emit/Scan[@Label="Scan:myobjectss"]' xmltest
152
Adaptive Server Enterprise
第4章
クエリ最適化方式と見積もりの表示
showplan_in_xml(-1)
then "PASSED" else "FAILED"
go
set plan for show_exec_xml off
go
set コマンドのパーミッション
sa role を持っているシステム管理者 (SA) は、前述の set コマンドに対して完全
なアクセス権を持っています。
ただし、その他のユーザの場合は、dbcc traceon/off (3604,3605) を動作させ、
XML に対する set option と set plan を許可するために、システム管理者が新
しい set tracing パーミッションの付与と取り消しを行う必要があります。
詳細については、『ASE リファレンス・マニュアル:コマンド』の grant コマ
ンドの記述を参照してください。
廃止になったトレース・コマンド
以前のバージョンの最適化トレース・オプション (dbcc traceon/off(302,310,317))
は、サポートされなくなりました。
クエリ・プロセッサ
153
XML フォーマット・メッセージの set コマンド
154
Adaptive Server Enterprise
第
5
章
クエリ処理 (QP) 測定基準
トピック名
クエリ処理 (QP) 測定基準とは
ページ
155
QP 測定基準の実行
156
測定基準のアクセス
156
測定基準の使用
156
測定基準のクリア
160
クエリ処理 (QP) 測定基準とは
クエリ処理測定基準とは、クエリの実行における経験的な測定基準値を識
別し、比較するためのものです。クエリが実行されると、QP 測定基準で
の比較の基礎となる定義済みの測定基準のセットがそのクエリに関連付
けられます。
次のような測定基準が取得されます。
•
CPU 実行時間 - クエリを実行するのにかかった時間 ( ミリ秒単位 )。
•
経過時間 - CPU 時間と、クエリの解析、コンパイル、最適化にか
かった時間 ( ミリ秒単位 )。経過時間はクエリ・プランがコンパイル
された後に記録されます。
•
論理 I/O - 論理 I/O 読み込みの回数。
•
物理 I/O - 物理 I/O 読み込みの回数。
•
カウント - クエリが実行された回数。
•
アボート・カウント - リソース制限を超えたために Resource Governor
によってクエリがアボートされた回数。
各測定基準には、最小、最大、平均の 3 つの値があります。ただし、カウ
ントとアボート・カウントは除きます。
クエリ・プロセッサ
155
QP 測定基準の実行
QP 測定基準の実行
QP 測定基準は、サーバ・レベルまたはセッション・レベルでアクティブにし
て使用することができます。
サーバ・レベルでは sp_configure に enable metrics capture オプションを指定
して使用します。アドホック文の qpmetrics はシステム・カタログ内に直接取
得され、ストアド・プロシージャに含まれる文の qpmetrics はプロシージャ・
キャッシュに保存されます。文キャッシュ内のストアド・プロシージャまたは
クエリがフラッシュされると、それに対応して取得された測定基準がシステ
ム・カタログに書き込まれます。
sp_configure "enable metrics capture", 1
セッション・レベルでは、set metrics_capture on/off を使用します。
set metrics_capture on/off
測定基準のアクセス
QP 測定基準は、各データベースのデフォルトの実行グループ ( グループ 1) 内
に常に取得されます。デフォルトの実行グループに保存した QP 測定基準を
バックアップ・グループに移すには、sp_metrics ‘backup’ を使用します。測定
基準情報には、sysquerymetrics ビューに対して order by を指定した select 文を
使用してアクセスします。
測定基準情報のソートと評価用の具体的なクエリを識別するために、データ操
作言語 (DML) 文を使用することもできます。
測定基準の使用
QP 測定基準によって生成された情報を使用して、次の内容を識別できます。
•
クエリ・パフォーマンス・リグレッション
•
実行されたクエリのバッチの中で最も「高コスト」のクエリ
•
最も頻繁に実行されるクエリ
問題を起こしている可能性のあるクエリに関する情報がある場合、効率を上げ
るためにクエリを調整することができます。
たとえば、
「高コスト」のクエリを識別して微調整することは、同一のバッチ
内にある「低コスト」のクエリを調整するよりも効果があります。
最も頻繁に実行されるクエリを識別し、効率を高めるためにそれらを微調整す
ることもできます。
156
Adaptive Server Enterprise
第5章
クエリ処理 (QP) 測定基準
クエリ測定基準を調整すると、実行されるそれぞれのクエリに余分な I/O を発
生させる可能性もあるので、パフォーマンス面の影響があることも考えられま
す。ただし、前述の利点も考慮すべきです。また、クエリ測定基準を利用する
ことが MDA テーブルで利用可能な情報と対比されると、クエリ測定基準を伴
うクエリに関する集約された履歴データが集計され、システム・カタログに格
納されることは意味がなくなります。MDA テーブル内の情報は一時的なもの
です。
QP 測定基準とモニタリング・テーブルのどちらを使用すべきか
QP 測定基準とモニタリング・テーブルには、どちらにも統計情報を集計する
場所があります。ただし、モニタリング・テーブルからの一時的な情報を持つ
のではなく、永続的なカタログに集約された履歴クエリ情報を集計する場合に
は、モニタリング・テーブルではなく QP 測定基準を使用します。
sysquerymetrics ビュー
フィールド
uid
クエリ・プロセッサ
定義
ユーザ ID
gid
グループ ID
id
ユニーク ID
hashkey
SQL クエリ・テキストにおける hashkey
sequence
SQL のテキストに複数ローが必要な場合の、あるローのシーケンス番号
exec_min
最短実行時間
exec_max
最長実行時間
exec_avg
平均実行時間
elap_min
最短経過時間
elap_max
最長経過時間
elap_avg
平均経過時間
lio_min
最小論理 I/O
lio_max
最大論理 I/O
lio_avg
平均論理 I/O
pio_min
最小物理 I/O
pio_max
最大物理 I/O
pio_avg
平均物理 I/O
cnt
クエリが実行された回数
abort_cnt
リソース制限を超えたときに Resource Governor によってクエリがア
ボートされた回数
qtext
クエリ・テキスト
157
測定基準の使用
このビューの平均値は次の式を使用して計算されます。
new_avg = (old_avg * old_count + new_value )/ (old_count + 1) = old_avg + round((new_value
- old_avg)/(old_count + 1))
次に示すのは、sysquerymetrics ビューの例です。
select * from sysquerymetrics
uid
gid
hashkey
id
sequence
exec_min
exec_max
exec_avg
elap_min
elap_max
elap_avg
lio_min
lio_max
lio_avg
pio_min
pio_max
pio_avg
cnt
abort_cnt
qtext
----------- ----------- ----------- ----------- ----------- --------------------- ----------- ----------- ----------- ----------- --------------------- ----------- ----------- ----------- ----------- ----------------------------------------------------------------------------------1
1
106588469
480001710
0
0
0
0
16
33
25
4
4
4
0
4
2
2
0
select distinct c1 from t_metrics1 where c2 in (select c2 from t_metrics2)
前述の例は、SQL 文のレコードを表示します。文のクエリ・テキストは select
distinct c1 from t_metrics1 where c2 in (select c2 from t_metrics2) です。この
文はこれまで 2 回実行されています (cnt = 2)。最短経過時間は 16 ミリ秒、最
長経過時間は 33 ミリ秒、平均経過時間は 25 ミリ秒です。全実行時間は 0 であ
り、これは CPU 実行時間が 1 ミリ秒よりも短かったためと思われます。最大
物理 I/O は 4 であり、最大論理 I/O と一致しています。ただし、2 回目の実行
ではデータがすでにキャッシュ内にあるため、最小物理 I/O は 0 になっていま
す。論理 I/O は 4 です。これは、データがメモリ内に存在するかどうかに関係
なく論理 I/O は静的であるためです。
例
QP 測定基準を使用すると、パフォーマンスのチューニングと可能なリグレッ
ションのために特定のクエリを識別することができます。
158
Adaptive Server Enterprise
第5章
クエリ処理 (QP) 測定基準
最も高いコストの文を識別する
通常、チューニングの候補となる最も高いコストの文を見つけるために、
sysquerymetrics によって、測定のオプションとして CPU 実行時間、経過時
間、論理 I/O、物理 I/O が提供されます。たとえば、典型的な測定値は論理 I/O
に基づいています。次のクエリを使用して、チューニングの候補となる過大な
I/O を発生させる文を検出します。
select lio_avg, qtext from sysquerymetrics order by lio_avg
lio_avg qtext
---------------------------------------------------------------2
select c1, c2 from t_metrics1 where c1 = 333
4
select distinct c1 from t_metrics1 where c2 in (select c2 from t_metrics2)
6
select count(t_metrics1.c1) from t_metrics1, t_metrics2,
t_metrics3 where (t_metrics1.c2 = t_metrics2.c2 and
t_metrics2.c2 = t_metrics3.c2 and t_metrics3.c3 = 0)
164
select min(c1) from t_metrics1 where c2 in (select t_metrics2.c2 from t_metrics2,
t_metrics3 where (t_metrics2.c2 = t_metrics3.c2 and t_metrics3.c3 = 1))
(4 個のローが影響を受けます )
上記の結果でチューニングに最適の候補は、平均論理 I/O の最大値を持つ最後
の文にあります。
最も頻繁にチューニングに使用される文を識別する
あるクエリが頻繁に使用される場合、微調整を行うと、そのパフォーマンスが
向上することがあります。order by を指定して select 文を使用することで、最
も頻繁に使用されるクエリを識別します。
select elap_avg, cnt, qtext from sysquerymetrics order by cnt
elap_avg cnt
qtext
----------- -----------------------------------------------------------0
1
select c1, c2 from t_metrics1 where c1 = 333
16
2
select distinct c1 from t_metrics1 where c2 in (select c2 from t_metrics2)
24
3
select min(c1) from t_metrics1 where c2 in (select t_metrics2.c2 from t_metrics2,
t_metrics3 where (t_metrics2.c2 = t_metrics3.c2 and t_metrics3.c3 = 1))
78
4
クエリ・プロセッサ
159
測定基準のクリア
select count(t_metrics1.c1) from t_metrics1, t_metrics2, t_metrics3 where (t_metrics1.c2
= t_metrics2.c2 and t_metrics2.c2 = t_metrics3.c2 and t_metrics3.c3 = 0)
(4 個のローが影響を受けます )
パフォーマンス・リグレッションの可能性を識別する
場合によって、サーバを新しいバージョンにアップグレードするときに、QP 測
定基準をパフォーマンスの比較に利用できることがあります。何らかのパフォー
マンスの低下が考えられるクエリを識別するには、次の処理を使用します。
1
これまでのサーバの QP 測定基準をバックアップ・グループにバックアッ
プします。
sp_metrics ‘backup’ <backup group ID>
2
新しいサーバに変更して QP 測定基準を有効にします。
sp_configure “enable metrics capture”, 1
3
以前のサーバと新しいサーバのレポートで QP 測定基準を比較して、リグ
レッションの問題を持つクエリを識別します。
測定基準のクリア
sp_metrics ‘flush’ を使用すると、メモリ内の集約された測定基準すべてをシス
テム・カタログにフラッシュできます。フラッシュ後、メモリ内のすべての文
に対する集約された測定基準はゼロになります。
システム・カタログから QP 測定基準を削除する場合は、次のコマンドを使用
します。
sp_metrics ‘drop’, <gid>, <id>
160
Adaptive Server Enterprise
第
6
章
抽象プラン
トピック名
新しいオペレータとその構文
ページ
162
新しいディレクティブとその構文
165
15.0 より前のオペレータのサポート
165
複雑なクエリの例
166
測定基準
167
ワーク・テーブルと手順
167
構文上の修飾
168
古くなった部分プラン
169
抽象プランとは、クエリ・プロセッサによって作成されるクエリ・プラン
の編集可能な表現です。抽象プランは、元になるクエリが実行されるとき
にはいつでも、取得したり、元になるクエリと関連付けたり、再使用した
りできます。また、select または他の SQL 文に plan 句を使用することで、
クエリに書き込むこともできます。
通常、オプティマイザは最も効率的なクエリ・プランを提供しますが、と
きには、特定のクエリが異なるジョイン順やサブクエリの異なる評価順序
などを要求することがあります。
抽象プランは次の目的に使用できます。
•
オプティマイザによって提供されるものとは異なる実行プランのク
エリを提供する
•
アップグレード前に、アップグレードによって発生する可能性のある
パフォーマンスの低下を防ぐために、クエリ・プランを取得する
また、抽象プランは、システムの大幅な変更の前後にクエリ・プランを取
得する手段も提供します。変更前と後の一連のクエリ・プランを比較する
ことにより、行った変更がクエリにどのような効果を及ぼすかを知ること
ができます。次のような機能もあります。
クエリ・プロセッサ
•
テーブル・スキャンや再フォーマットなど、特別なタイプのプランを
検索する。
•
特定のインデックスを使用するプランを検索する。
•
最適化に時間がかかるクエリのプランを保存する。
161
新しいオペレータとその構文
抽象プランは、バッチまたはクエリの中でオプティマイザの判断を操作するた
めにオプションを指定する代わりに使用します。抽象プランを使用すると、
SQL 文を、構文を変更せずに最適化結果を変更できます。クエリ・テキスト
を格納しているテキストと比較して一致を見つける作業には処理のための
オーバヘッドがかかりますが、保存されているプランを使うことによりクエリ
最適化のためのオーバヘッドが減ります。
Adaptive Server 15.0 は、抽象プランに対する強化されたアプローチをサポート
しています。Adaptive Server 15.0 では、抽象プラン言語の構造は変更されてい
ませんが、新しいオペレータを数多くサポートしており、それぞれのオペレー
タが処理アルゴリズムに直接対応するようになりました。
新しいオペレータとその構文
表 6-1 は、新しい抽象プランとその構文を示します。15.0 以前のオペレータの
いくつかは引き続きサポートされており、その一覧は「15.0 より前のオペレー
タのサポート」(165 ページ ) に示します。それぞれの抽象プランのオペレータ
はクエリ・エンジンで使用される演算子に対応しています。たとえば、h_join
は hash join 演算子に対応しており、hash_union_distinct は重複削除を行うハッ
シュベースの n 項和集合 (hash distinct) に対応しています。
注意 非抽出テーブルオペレータの変更はほとんどありません。
新しいオペレータの完全な説明については、
「付録 A 抽象プランの仕様」を参
照してください。
表 6-1: 抽象プランの抽出テーブル・オペレータ
オペランド
の数
オペレータの
タイプ
null 項 - 0
保管されてい
るテーブルの
スキャン
単項 - 1
162
構文
説明
(scan stored_table)
テーブルまたはインデックスのスキャンを指
定する。
(t_scan stored_table)
テーブルのスキャンを指定する。
(i_scan stored_index
stored_table)
stored_index インデックスを使用して、
stored_table
テーブルのインデックス・スキャンを指定する。
テーブル・リテ
ラル・スキャン
(scan_values)
select 1 などのリテラル値のスキャンを指定
する。
実行
(sort derived_table)
derived_table をソートする。ソートするカラム
は自動的に決定される。
(xchg degree derived_table)
derived_table を再分割して、ストリーム数を
degree の値と同じにする。
(store_index derived_table)
derived_table の再フォーマット化を示す。
Adaptive Server Enterprise
第6章
オペランド
の数
抽象プラン
オペレータの
タイプ
構文
説明
重複削除
(distinct derived_table)
derived_table に対する重複削除の実現を示す。
(distinct_sorted derived_table)
derived_table でデータのソートを実際に行うこ
となく重複を削除することで重複削除を実現
する。
制限事項:derived_table は、重複削除が必要な
カラムでソートされている必要がある。
グループ化
2項-2
ジョイン
(distinct_sorting derived_table)
重複削除が必要になるカラムに対してソート
によって重複削除を実現する。
(distinct_hashing derived_table)
重複 削除が必 要になる カラム に対して ハッ
シュによって重複削除を実現する。
(group derived_table)
derived_table に対する SQL グループ化オペレー
ションを示す。
(group_sorted derived_table)
derived_table 内のデータを実際にソートするこ
となく、集合関数を実行することでグループ化
を示す。derived_table のデータはグループ化カ
ラムでソートされていることが前提である。
(group_hashing derived_table)
グループ化カラムをハッシュし、同時に集合関
数を実行することで、グループ化を示す。
(join derived_table1
derived_table2)
derived_table1 のデータを derived_table2 のデー
タに SQL ジョインすることを示す。ジョイン
するカラムは SQL クエリによって自動的に決
定される。
(nl_join derived_table1
derived_table2)
nested loop joins のアルゴリズムを使用して、
derived_table1 のデータを derived_table2 のデー
タに SQL ジョインすることを示す。
(m_join derived_table1
derived_table2)
merge joins のアルゴリズムを使用して、
derived_table1 のデータを derived_table2 のデー
タに SQL ジョインすることを示す。
制限事項::derived_table1 および derived_table2
は、等価ジョイン述部のカラムに対してソート
される必要がある。
制限事項:merge join は、2 つの抽出テーブル
が 1 つ以上の等価ジョイン述部で接続されて
いる場合に限り実行できる。
(h_join derived_table1
derived_table2)
hash joins のアルゴリズムを使用して、
derived_table1 のデータを derived_table2 のデー
タに SQL ジョインすることを示す。
制限事項:hash join は、2 つの抽出テーブルが
1 つ以上の等価ジョイン述部で接続されている
場合に限り実行できる。
ネスト・サブク
エリ
クエリ・プロセッサ
(nested derived_table subquery)
サブクエリ自体の抽象プランによって指定さ
れたサブクエリが、derived_table で指定された
抽出テーブルのスキャン中に評価されること
を示す。
163
新しいオペレータとその構文
オペランド
の数
n項-N
オペレータの
タイプ
和集合
構文
説明
(union derived_table1
derived_table2 ...)
derived_table1、derived_table2 などと指定される
抽出テーブルに対して実行される SQL union
オペレーションを指定する。
(_union_distinct derived_table1
derived_table2 ...)
merge 用のアルゴリズムを使用して、
derived_table1、derived_table2 と指定される抽
出テーブルに対して実行される SQL union オ
ペレーションを指定する。
制限事項:各抽出テーブルは、基本となるクエ
リの select リストでカラムに対してソートさ
れている必要がある。
(h_union_distinct derived_table1
derived_table2 ...)
ハッシュベースのアルゴリズムを使用して、
derived_table1、derived_table2 と指定される抽出
テーブルに対して実行される SQL union オペ
レーションを指定する。
(m_union_all derived_table1
derived_table2 ...)
基本となる各クエリの select リストにある少
なくとも 1 つのカラムへの順序付けが維持さ
れる merge アルゴリズムを使用して、
derived_table1、derived_table2 と指定される抽
出テーブルに対して実行される SQL union all
オペレーションを指定する。
制限事項:各抽出テーブルは、基本となるクエ
リの select リストでカラムに対してソートさ
れている必要がある。
順序付け
164
union_all derived_table1
derived_table2 ...)
抽出テーブルを次々に追加していくことで、
derived_table1、derived_table2 などと指定される
抽出テーブルに対して実行される SQL union
all オペレーションを指定する。
(sequence derived_table1
derived_table2 ...derived_tableN)
derived_table1、derived_table2 などがすべて処
理されてから、derived_tableN と表される最後
の抽出テーブルがアクセスされる必要がある
ことを指定する。通常、derived_tableN は
derived_table1、derived_table2 などの抽出テー
ブルのいずれかによって作成される結果セッ
トによって異なる。
Adaptive Server Enterprise
第6章
抽象プラン
新しいディレクティブとその構文
Adaptive Server 15.0 は、抽象プラン・メカニズムによって最適化目標と最適化
タイムアウト時間に対するクエリ・レベルのディレクティブをサポートしてい
ます。このようなディレクティブは use キーワードによって指定できます ( 詳
細については「付録 抽象プランの仕様」を参照してください )。次の例では、
抽象プランでの use ディレクティブの指定を強調表示しています。
最適化目標
この例では、allrows_dss 最適化目標のクエリ・レベル指定を強調表示しています。
select * from publishers p, titles t
where t.pub_id = p.pub_id
plan
“(use optgoals allrows_dss)”
最適化タイムアウト時間
この例では、最適化タイムアウト時間のクエリ・レベル指定を強調表示してい
ます。
select * from publishers p, titles t
where t.pub_id = p.pub_id
plan
“(use opttimeoutlimit 100)”
15.0 より前のオペレータのサポート
Adaptive Server は、次に示す 15.0 より前のオペレータをサポートしています
が、オプティマイザがこれらを生成することはありません。
•
g_join および nl_g_join - join および nl_join に置き換えられた。
バージョン 15.0 では、オプティマイザが、使用するジョイン測定基準を
決定します。Adaptive Server が、内部ジョイン、外部ジョイン、またはセ
ミジョインを強制できる抽象プラン構文を提供することはありません。
•
plan - ワーク・テーブルまたはスカラ結果によって通常接続される一連
の手順を示す。
バージョン 15.0 では、Adaptive Server は実際の関係演算子を使用し、ワー
ク・テーブルを隠しています。サーバは plan を、バージョン 15.0 の対応
するオペレータで解析します。共有ワーク・テーブルや非相関サブクエリ
などで処理手順が必要になると、混乱を避けるために sequence を使用し
ます。
クエリ・プロセッサ
165
複雑なクエリの例
複雑なクエリの例
select r1, sum(s1) from r, s
where r2=s2
group by r1
union
select t1, u2
from t, u
where t1=u1
order by 1
plan
"(merge_union_all
(group_sorted
(nl_join
(i_scan ir1 r)
(i_scan is2 s)
)
)
(m_join
(i_scan it1 t)
(i_scan iu1 u)
)
)”
この例では、merge_union_all によって最初のカラムでソートされた結果セッ
トを提供するようにクエリ・プランに強制しています。
これは順序付けされたオペランドに依存しています。和集合オペランドは次の
ものを使用しています。
166
•
group_sorted - 外部の子である i_scan ( インデックス・カラムによる順
序付けを生成する) の順序付けは維持するものの自身の順序付けは必要と
しない子である nl_join から提供される順序付けによって実行中にベクト
ル集合演算を行います。
•
m_join ( マージ・ジョイン ) - 等価ジョイン句カラムで順序付けされる子
に依存します。そのどちらのオペランドも、必要な順序付けを生成するカ
ラムの i_scan になります。
Adaptive Server Enterprise
第6章
抽象プラン
測定基準
Adaptive Server 15.0 は、各抽象プランの妥当性を検査して、アルゴリズムを
誤って使用する抽象プランを拒否します。
たとえば、Adaptive Server は次の抽象プランを拒否します。その理由は、t_scan
が group_sorted によって必要とされる順序付けを生成しないためです。
select r1, sum(r2)
from r
group by r1
plan
"(group_sorted (t_scan r))”
ワーク・テーブルと手順
Adaptive Server 15.0 はワーク・テーブルを公開しません。ワーク・テーブルは、
特殊な場合を除き、演算子の実装詳細のことです。
次の例で、ソートは distinct_sorting で実装されるので、ソート側のワーク・
テーブルは不必要です。
select *
from
r,
(select distinct s1 from s) as d(d1)
where r1=d1
plan
"(m_join
(distinct_sorting
(t_scan s)
)
(i_scan ir1 r)
)”
次の 2 番目の例ではワーク・テーブルが必要になります。クエリ・プランは 2
つの手順を使用します。最初の手順で、distinct ビューの結果がワーク・テー
ブルとして実体化されます。2 番目の手順はセルフジョインを実行します。
ワーク・テーブルは 2 回スキャンされ、ジョインされるので、アルゴリズムの
詳細ではなくなります。
create view v(v1, v2)
as select distinct s1, s2 from s
select * from v a, v b
where a.v1 = b.v2
plan
"(sequence
(store
(distinct_hashing
クエリ・プロセッサ
167
構文上の修飾
(t_scan s)
)
)
nl_join
(t_scan (table (w_table 1 a v)))
(t_scan (table (w_table1 b v))))
)”
構文上の修飾
15.0 よりも前のバージョンでは、テーブル名の構文上の修飾が必要でした。
Adaptive Server 15.0 で、テーブル名の構文上の修飾が必要になるのは、あいま
いさによって結果が異なる可能性がある場合のみになります。
次の例では、s テーブルと t テーブルの間には何のあいまいさもないので修飾
は必要ありません ( 以前のバージョンの Adaptive Server では修飾が必要とされ
てきました )。
select * from t where t1 in (select s2 from s)
plan
"(nl_join
(t_scan t)
(t_scan s)
)”
次の例では、t テーブルが 2 か所にあるのであいまいになる可能性があり、こ
れら 2 つを区別するために修飾が必要になります。
select * from t where t1 in (select t2 from t)
plan
"(nl_join
(t_scan t)
(t_scan (table t (in (subq 1))))
)”
168
Adaptive Server Enterprise
第6章
抽象プラン
古くなった部分プラン
Adaptive Server 15.0 は、空のヒントは受け付けますが、適用はしなくなりました。
次の例では、m_join がクエリ・ツリーのリーフに抽象プランを指定している
ので適用されます。ただし、Adaptive Server は、group と union が () という無
視される空のヒントの上にあるのでこれらを無視します。
select r1, sum(s1)
from r, s
where r2 = s2
group by r1
union
select t1, u2
rom t, u
where t1 = u1
order by 1
plan
"(merge_union_all
(group_sorted
( )
)
(m_join
(i_scan it1 t)
(i_scan iu1 u)
)
)”
クエリ・プロセッサ
169
古くなった部分プラン
170
Adaptive Server Enterprise
第
7
章
パフォーマンス改善のための統計値の
使用
正確な統計値はクエリ最適化に必須です。先行のインデックス・キーでな
いカラムに対して統計値を追加すると、クエリのパフォーマンスが向上す
る場合もあります。この章では、統計値を管理するコマンドの使用方法に
ついて説明します。
トピック名
Adaptive Server で管理される統計値
ページ
171
統計値の重要性
172
統計値の更新
173
update statistics コマンド
174
統計の自動更新
176
自動 update statistics の設定
179
カラム統計値と統計値管理
183
カラム統計値の作成と更新
184
ヒストグラムのステップ数の選択
186
update statistics 実行時のスキャン・タイプ、ソートの稼働条
件、ロック
187
delete statistics コマンドの使用
190
ロー・カウントが不正確な場合
191
Adaptive Server で管理される統計値
これらの主要なオプティマイザ統計値は、Adaptive Server Enterprise で管理
されます。
クエリ・プロセッサ
•
テーブルごとの統計値:テーブルのロー・カウント、テーブルのペー
ジ・カウント。systabstats に含まれています。
•
インデックスごとの統計値:インデックスのロー・カウント、イン
デ ッ ク ス の 高 さ、イ ン デ ッ ク ス の リ ー フ・ペ ー ジ・カ ウ ン ト。
systabstats に含まれています。
•
カラムごとの統計値:データの分散。sysstatistics に含まれています。
•
カラム・グループの統計値:密度情報。sysstatistics に含まれています。
•
パーティションごとの統計値
171
統計値の重要性
•
パーティション・データ:パーティションのデータ・ロー・カウン
ト、パーティションのデータ・ページ・カウントです。systabstats に
含まれています。
•
パーティション・インデックス:パーティションのインデックス・
ロー・カウント、パーティションのインデックス・ページ・カウント
です。systabstats に含まれています。
•
カラムの統計値:カラムごとのデータの分布、カラムのグループごと
の密度。sysstatistics に含まれています。
定義
これらの定義は、この章の内容を理解するのに役立ちます。
密度
密度とは、指定されたカラム値のユニーク性を統計的に測定したものです。
ヒストグラム
ヒストグラムとは、指定した関連カラムの値の分布を統計的に表現したもの
です。
統計値の重要性
Adaptive Server のコスト・ベースのオプティマイザは、クエリ内で指定された
テーブル、インデックス、パーティション、カラムについての統計値を使用し
て、クエリのコストを見積もります。オプティマイザは、最小コストであると
判断したアクセス・メソッドを選択します。しかし統計値が正確でないと、正
確なコストを見積もれません。
統計値の中には、テーブル中のページ数やロー数のように、クエリ処理中に更
新されるものがあります。また、カラムのヒストグラムのように、update
statistics を実行したときやインデックスを作成したときにだけ更新される統
計値もあります。
クエリの実行が遅くてテクニカル・サポートに問い合わせたり、インターネッ
トで Sybase のニュースグループを参照する場合、こちらからの最初の質問の
1 つとして、よく「update statistics を実行しましたか ?」と聞かれることがあ
ります。このような場合、統計が存在する各カラムで update statistics が最後
に実行されたのはいつかを知るために、optdiag コマンドを使用できます。次
にその出力例を示します。
カラム統計の最終更新: Aug 31 2004 4:14:17:000PM
統計値の管理に必要なもう 1 つのコマンドは、delete statistics です。インデッ
クスを削除しても、そのインデックスの統計値は削除されません。インデック
スの削除後にカラム中でキーの分布が変わっても、統計値がいくつかのクエリ
にそのまま使用されていると、古くなった統計値がクエリ・プランに影響を与
えます。
172
Adaptive Server Enterprise
第7章
パフォーマンス改善のための統計値の使用
統計値の更新
update statistics コマンドは、ヒストグラムや密度などの、カラム関連の統計値を
更新します。インデックス中のキー分布に、クエリでのインデックス使用に影響
するような変更が発生したカラムでは、統計値を更新する必要があります。
update statistics の実行には、システム・リソースが必要です。他の管理タス
クと同様、コマンドの実行は、サーバの負荷が軽い時間にスケジュールする必
要があります。特に update statistics はインデックスのテーブル・スキャンか
リーフレベル・スキャンを必要とし、I/O 競合が増加したり、ソートの実行の
ために CPU を使用したり、データ・キャッシュとプロシージャ・キャッシュ
を使用したりします。このようにリソースを使用するため、使用率が高いとき
に update statistics を実行すると、サーバ上で実行するクエリのパフォーマン
スが低下することがあります。さらに、update statistics コマンドには、更新
をブロックする共有ロックが必要です。詳細については、
「update statistics 実行
時のスキャン・タイプ、ソートの稼働条件、ロック」(187 ページ ) を参照して
ください。
システム・リソースへの影響が少ない時間帯に update statistics が自動的に実行
されるように、Adaptive Server を設定することもできます。詳細については、
「統計の自動更新」(176 ページ ) を参照してください。
インデックス未設定カラムへの統計値の追加
インデックスを作成するとき、インデックス内の先行カラムのヒストグラムが
生成されます。別の章では、他のカラムの統計値がオプティマイザ統計値の正
確性をどのように高めるかについて説明しています。
探索引数として頻繁に使用されるすべてのカラムに対して、統計値の追加を検
討し、管理スケジュールの許す限り、これらの統計値を最新のものに保ってく
ださい。
特に、先行のインデックス・キーとともに複合インデックスのマイナー・カラ
ムが探索引数やジョインで使用されている場合、複合インデックスのマイ
ナー・カラムに統計値を追加すると、コスト見積もりを大幅に改善できます。
クエリ・プロセッサ
173
統計値の更新
update statistics コマンド
update statistics コマンドは、特定のカラムに統計値がない場合は統計値を作成
し、すでに存在する場合は既存のものと置き換えます。統計値は、システム・
テーブル systabstats と sysstatistics に格納されます。構文は次のとおりです。
update statistics table_name
[[ partition data_partition_name ] [ (column_list ) ] |
index_name [ partition index_partition_name ] ]
[ using step values ]
[ with consumers = consumers] [, sampling=percent]
update index statistics
table_name [[ partition data_partition_name ] |
[ index_name [ partition index_partition_name ] ] ]
[ using step values ]
[ with consumers = consumers] [, sampling=percent]
update all statistics table_name
[ partition data_partition_name ]
update table statistics
table_name [partition data_partition_name ]
delete [ shared ] statistics table_name
[ partition data_partition_name ]
[( column_name[, column_name ] ...)]
コマンドの効果とパラメータについて説明します。
•
174
update statistics の場合:
•
table_name - テーブル上にある各インデックス内の先行カラムの統
計値を生成。
•
table_name index_name - インデックスの全カラムの統計値を生成。
•
partition_name - このパーティションのみの統計値を生成。
•
partition_name table_name (column_name) - このパーティションにあ
るこのテーブルのこのカラムの統計値を生成。
•
table_name (column_name) - このカラムの統計値だけを生成。
•
table_name (column_name, column_name...) - セット内の先行カラムの
ヒストグラムとプレフィクス・サブセットに対する複数カラムの密度
値を生成。
•
using step values - 使用するステップ数を指定。デフォルトのステッ
プ数は 20。デフォルトのステップ数を変更する必要がある場合は、
sp_configure を使用する。
•
sampling = percent - サンプリング率を示す数値。たとえば 05 は 5%
を、10 は 10% を表す。サンプリング率には 0 ~ 100 の範囲の整数を
指定。
Adaptive Server Enterprise
第7章
•
•
パフォーマンス改善のための統計値の使用
update index statistics の場合:
•
table_name - テーブル上にある全インデックス内の全カラムの統計
値を生成。
•
partition_name table_name - パーティションのテーブル上にある全イ
ンデックス内の全カラムの統計値を生成。
•
table_name index_name - このインデックスの全カラムの統計値を生成。
update all statistics の場合:
•
table_name - テーブルの全カラムの統計値を生成。
•
table_name partition_name - パーティションのテーブル上にある全カ
ラムの統計値を生成。
•
using step values - 使用するステップ数を指定。デフォルトのステップ数
は 20。デフォルトのステップ数を変更するには、sp_configure を使用す
る。sp_configure の新しいオプションは histogram tuning factor で、ヒス
トグラムのステップ数をより高度に選択できる。sp_configure の詳細に
ついては、
『システム管理ガイド』を参照。
update statistics へのサンプリングの使用
Adaptive Server のオプティマイザは、データベースの統計値を使用してクエリ
の設定と最適化を行います。最良の結果を得るには、統計値ができるかぎり最
新のものであることが必要です。
テーブルなどのデータ・セットに対して update statistics コマンドを実行すると、
指定したインデックスまたはカラム内、インデックス内のすべてのカラム、あ
るいはテーブル内のすべてのカラムのキー値の分布に関する情報が更新されま
す。また、カラムレベル統計のヒストグラムと密度値も更新されます。オプティ
マイザはその結果を使用してクエリ・プランの最適な設定を計算します。
update statistics はインデックスのテーブル・スキャンかリーフレベル・スキャ
ンを必要とし、I/O 競合が増加したり、ソートの実行のために CPU を使用した
り、データ・キャッシュとプロシージャ・キャッシュを使用したりします。こ
のようにリソースを使用するため、使用率が高いときに update statistics を実
行すると、サーバ上で実行するクエリのパフォーマンスが低下することがあり
ます。さらに、update statistics コマンドには、更新をブロックする共有ロッ
クが必要です。
I/O の競合とリソースを減らすには、サンプリング方式を使用して update
statistics を実行します。これにより、メンテナンス時間が少なく、データ・
セットが大きい場合の I/O と時間を削減できます。常時使用され、トランケー
トおよび再移植される大規模なデータ・セットまたはテーブルを更新する場合
は、統計的サンプリングを行うことによって、時間と I/O サイズを削減できま
す。サンプリングでは密度値を更新しないため、正確な密度値のサンプリング
を使用する前に、完全な update statistics を実行する必要があります。
クエリ・プロセッサ
175
統計の自動更新
結果が十分に正確とは限らないので、サンプリングには注意が必要です。ヒス
トグラム値の変化と I/O の節減のバランスをとってください。
データ・セットのサンプリングは完全に正確とは言えませんが、通常はヒスト
グラムも密度値も許容範囲内に収まります。
サンプリングを使用するかどうかを判断するときは、データ・セットのサイ
ズ、作業時間の制約、生成されるヒストグラムが必要な程度に正確であるかを
考慮に入れてください。
サンプリングで使用するパーセンテージは要件に応じて異なります。特定の
データ・セットについての情報を最も正確に反映した結果が得られるまで、さ
まざまなパーセンテージをテストしてください。
例:
update statistics authors(auth_id) with sampling = 5 percent
サーバワイドなサンプリング率は、次のようにして設定できます。
sp_configure 'sampling percent', 5
このコマンドは、update statistics のサーバワイドのサンプリング率を 5% に
設定します。これにより、sampling 構文を使用せずに update statistics を実行
できるようになります。0% ~ 100% までの任意のパーセンテージを指定でき
ます。
統計の自動更新
Adaptive Server のコスト・ベースのクエリ・オプティマイザは、クエリ内で指
定されたテーブル、インデックス、カラムについての統計値を使用して、クエ
リのコストを見積もります。これらの統計値に基づいて、クエリ・プロセッサ
は、最小コストであると判断したアクセス・メソッドを選択します。しかし統
計値が正確でないと、正確なコストを見積もれません。統計値が最新のもので
あることを確実にするために、update statistics を実行することができます。し
かし、update statistics を実行すると、CPU、バッファ・プール、ソート・バッ
ファ、プロシージャ・キャッシュなどのシステム・リソースが消費されるた
め、関連するコストがかかります。
特定の時刻に手動で update statistics を実行する代わりに、このコマンドの実行
がシステムに支障を来すことのない都合のよい時間帯に update statistics が自
動実行されるように設定することができます。update statistics を実行するの
に最適な時間帯は、datachange 関数からのフィードバックに基づいて決定し
ます。また、datachange は、update statistics を不要に実行することを防ぐの
に役立ちます。テンプレートを使用して、オブジェクト、スケジュール、優先
度、update statistics をトリガする datachange スレッショルドを指定すること
により、クエリ・プロセッサによってより効率的なプランが生成されたときに
のみ重要なリソースが使用されるようにすることができます。
176
Adaptive Server Enterprise
第7章
パフォーマンス改善のための統計値の使用
update statistics の実行には多量のリソースが必要なので、実行するかどうか
は特定の条件に基づいて決定します。update statistics を実行する適切なタイ
ミングを決定するのに役立つ主なパラメータとしては、次のものがあります。
•
前回 update statistics を実行してからデータ特性がどの程度変化したか。
これは、datachange パラメータでわかります。
•
update statistics を実行するのに十分なリソースが使用可能であるか。こ
れには、アイドル CPU サイクルの数などのリソースが含まれます。また、
update statistics の実行中に重要なオンライン・アクティビティが発生し
ないことも確認する必要があります。
datachange は、前回 update statistics を実行してから変更されたデータの量を測
定するのに役立つ重要な測定基準であり、datachange 関数によって観測できま
す。この測定基準とリソース使用可能性の条件を使用することで、update
statistics を実行する処理を自動化できます。Job Scheduler は、update statistics
を自動的に実行するためのメカニズムを備えています。Job Scheduler には、
update statistics をいつ実行するかを決定する、カスタマイズ可能なテンプレー
トのセットが含まれています。これらの入力には、update statistics へのすべて
のパラメータ、datachange スレッショルド値、update statistics を実行する時
刻などがあります。Job Scheduler は update statistics を低い優先度で実行するの
で、同時に実行される重要なジョブに影響を与えることはありません。
datachange 関数とは
datachange 関数によって、update statistics が最後に実行された後にデータ分配
で行われた変更の量が測定されます。具体的には、指定のオブジェクト、パー
ティション、カラムで発生した挿入、更新、削除の数が測定されます。これ
は、update statistics の実行がクエリ・プランに役立つかどうかを判断する目安
になります。
次に、datachange の構文を示します。
select datachange( object_name, partition_name, colname)
各パラメータの内容は、次のとおりです。
•
object_name - オブジェクト名です。このオブジェクトは、現在のデータ
ベースにあると見なされます。このパラメータは必須です。null にするこ
とはできません。
•
partition_name - データ・パーティション名です。null 値を使用できます。
•
colname - datachange が要求されるカラムの名前です。null 値を使用で
きます。
datachange 関数には 3 つのパラメータをすべて指定する必要があります。
クエリ・プロセッサ
177
統計の自動更新
datachange は、テーブルまたはパーティション ( パーティションを指定した
場合 ) 内の合計ロー数のパーセンテージとして表されます。パーセンテージの
値は 100 パーセントを超えることがあります。これは、オブジェクトの変更回
数が、テーブル内のロー数を大幅に超える場合があるからです。特に、1 つの
テーブルで削除と更新が非常に多く行われるとこの状況になります。
次の各例では、datachange 関数のさまざまな使用法について示します。これ
らの例では、次のような内容を使用しています。
有効なオブジェクト名、
パーティション名、カラ
ム名の引き渡し
•
オブジェクト名は “O”。
•
パーティション名は “P”。
•
カラム名は “C”。
オブジェクト名、パーティション名、およびカラム名を含める場合にレポート
される値は、次のような等式によって決定されます ( パーティションのローカ
ウントによって除算される指定されたパーティションの指定されたカラムの
datachange 値 )。結果はパーセンテージで表されます。
datachange = 100 * (data change value for column C/ rowcount (P))
null のパーティション名
の使用
null パーティション名を含める場合、datachange 値は次のような等式によっ
て決定されます ( テーブルのローカウントによって除算されるすべてのパー
ティションのカラムの datachange 値の合計 )。結果はパーセンテージで表さ
れます。
datachange = 100 * (Sum(data change value for (O, P(1-N) , C))/rowcount(O)
P(1-N) は、値がすべてのパーティションで合計されることを示します。
null のカラム名の使用
null カラム名を含める場合、datachange によってレポートされる値は次のよ
うな等式によって決定されます ( パーティションのローの数によって除算され
る指定されたパーティションのヒストグラムを持つすべてのカラムの
datachange の最大値 )。結果はパーセンテージで表されます。
datachange = 100 * (Max(data change value for (O, P, Ci))/rowcount(P)
i の値は、ヒストグラムを持つカラムによって変わります ( たとえば、sysstatistics
の formatid 102)。
null のパーティション名
とカラム名
null のパーティション名とカラム名を含める場合、datachange の値は次のよ
うな等式によって決定されます ( テーブルのローの数によって除算されるすべ
てのパーティションで合計されるヒストグラムを持つすべてのカラムの
datachange の最大値 )。結果はパーセンテージで表されます。
datachange = 100 * ( Max(data change value for (O, NULL, Ci))/rowcount(O)
i の値は、ヒストグラムを持つカラムの合計数において 1 です ( たとえば、
sysstatistics の formatid 102)。
次のセッションは、datachange による統計値の収集を示します。
create table matrix(col1 int, col2 int)
go
insert into matrix values (234, 560)
178
Adaptive Server Enterprise
第7章
パフォーマンス改善のための統計値の使用
go
update statistics matrix(col1)
go
insert into matrix values(34,56)
go
select datachange ("matrix", NULL, NULL)
go
-----50.000000
matrix にあるローの数は 2 です。最後の update statistics コマンド以降に変更
されたデータの量は 1 なので、datachange のパーセンテージは 100 * 1/2 = 50
パーセントです。
datachange のカウンタは、すべて「メモリ内」で管理されます。これらのカ
ウンタは、ハウスキーパーまたは sp_flushstats の実行時に定期的にディスク
にフラッシュされます。
自動 update statistics の設定
統計値を自動的に更新するには、次の 3 つの方法があります。
•
Job Scheduler で update statistics ジョブを定義する。
•
Self Mamagement インストールの一部として、update statistics ジョブを定
義する。
•
ユーザ定義スクリプトを作成する。
ユーザ定義スクリプトの作成については、このマニュアルでは説明されていま
せん。
Job Scheduler を使用した統計値の更新
Job Scheduler には Update Statistics テンプレートが含まれており、テーブル、イ
ンデックス、カラム、またはパーティションで update statistics を実行するジョ
ブを作成するために使用できます。datachange 関数は、テーブルまたはパー
ティションでの変更の量が、事前に定義されたスレッショルドに達したかどう
かを判断します。ユーザは、テンプレートを設定するときに、このスレッショ
ルドの値を決定します。
テンプレートは、次のようなオペレーションを実行します。
•
クエリ・プロセッサ
特定のテーブル、パーティション、インデックス、またはカラムで update
statistics を実行する。このテンプレートで、update statistics を実行する
datachange の値を定義できる。
179
自動 update statistics の設定
•
update statistics をサーバ・レベルで実行する。このコマンドは、ジョブ
の作成時に決定したスレッショルドを基に、Adaptive Server がサーバ上の
すべてのデータベースで使用可能なテーブルをスイープし、すべてのテー
ブルで統計値を更新するよう設定する。
次の手順を使用して、update statistics を実行するプロセスを自動化するため
に Job Scheduler を設定します ( 下記に記載された章は『Job Scheduler ユーザー
ズ・ガイド』からの章を示します )。
1
Job Scheduler をインストールし、設定します ( 第 2 章「Job Scheduler の設
定と実行」で説明 )。
2
テンプレートに必要なストアド・プロシージャをインストールします ( 第
4 章「ジョブ・スケジューリングへのテンプレートの使用」で説明 )。
3
テンプレートをインストールします。Job Scheduler は、統計値を自動的に
更新するためのテンプレートを提供します ( 第 4 章「ジョブ・スケジュー
リングへのテンプレートの使用」で説明 )。
4
テンプレートを設定します。統計値を自動的に更新するテンプレートが、
Statistics Management フォルダにリストされます。
5
ジョブをスケジュールします。追跡するインデックス、カラム、または
パーティションを定義した後、Adaptive Server がいつジョブを実行するか
を決定するスケジュールも作成できます。update statistics は、パフォー
マンスに影響を与えない場合にだけ実行されるようにします。
6
成功か、失敗かを確認します。Job Scheduler のインフラストラクチャで
は、自動 update statistic の成功または失敗を確認することができます。
テンプレートを使用すると、サンプリング率、コンシューマの数、ステップな
ど、update statistics コマンドのさまざまなオプションの値を指定できます。オ
プションで、datachange 関数、ページ・カウント、ロー・カウントのスレッ
ショルド値も指定できます。これらのオプションの値を指定した場合は、その
値によって Adaptive Server がいつ update statistics コマンドを実行するかどうか
が決まります。テーブル、カラム、インデックス、またはパーティションのい
ずれかの現在の値がスレッショルド値を超えた場合、Adaptive Server は update
statistics を実行します。Adaptive Server が update statistics を実行した後、テン
プレートに指定されたテーブルに対して sp_recompile が実行されます。
Adaptive Server はいつ
update statistics を実行
するか
update statistics コマンドには多数の形式があり (update statistics、update index
statistics など )、必要に応じてさまざまな方法でコマンドを形成できます。
ユーザは、rowcount、pagecount、および datachange の 3 つのスレッショル
ドを指定する必要があります。update statistics が実行されるには、すべての
スレッショルドが満たされなければなりません。NULL または 0 は無視されま
すが、これらの値はコマンドの実行を妨げるものではありません。
表 7-1 は、ユーザが指定したパラメータの値に基づいて、Adaptive Server が自
動的に update statistics を実行する状況について説明しています。
180
Adaptive Server Enterprise
第7章
パフォーマンス改善のための統計値の使用
表 7-1: Adaptive Server が自動的に update statistics を実行する時期
ユーザが実行する動作
Job Scheduler によって実行される動作
datachange スレッショルドにゼロまたは NULL を
指定する。
スケジュールされた時間に update statistics を実行する。
テーブルのみに対してゼロより大きい datachange
スレッショルドを指定し、update index statistics の
形式は要求しない。
テーブル上にあるすべてのインデックスを取得し、各イン
デックスの先行カラムを取得する。いずれかの先行カラムの
datachange がスレッショルド以上の場合、update statistics を
実行する。
テーブルとインデックスのスレッショルド値を指定
し、update index statistics の形式は要求しない。
インデックスの先行カラムの datachange 値を取得する。
datachange 値がスレッショルド以上の場合、
update statistics
を実行する。
テーブルのみのスレッショルド値を指定し、update
index statistics の形式を要求する。
テーブル上にあるすべてのインデックスを取得し、各イン
デックスの先行カラムを取得する。いずれかの先行カラムの
datachange がスレッショルドを超える場合、update statistics
を実行する。
テーブルとインデックスのスレッショルド値を指定
し、update index statistics の形式を要求する。
インデックスの先行カラムの datachange 値を取得する。
datachange 値がスレッショルド以上の場合、
update statistics
を実行する。
テーブルと 1 つ以上のカラムのスレッショルド値を
指定 す る ( す べて の イン デ ック ス また は update
index statistics の形式の要求を無視する )。
各カラムの datachange 値を取得する。いずれかのカラムの
datachange がスレッショルド以上の場合、update statistics
を実行する。
datachange 関数はテーブルでの変更数をコンパイルし、それをテーブルの合
計ロー数の割合として表示します。このコンパイル情報は、Adaptive Server が
いつ update statistics を実行するのかを決定するルールを作成するために使用
できます。これを行う最適な時期は、数々の目的に基づいています。
•
テーブルにおける変更の割合。
•
使用できる CPU サイクルの数。
•
メンテナンス時間中。
update statistics が実行された後、datachange のカウンタはゼロに再設定されま
す。datachange のカウンタは、( オブジェクト・レベルではなく ) パーティショ
ン・レベルの挿入と削除およびカラム・レベルの更新のときに追跡されます。
クエリ・プロセッサ
181
自動 update statistics の設定
datachange を使用した統計値の更新の例
カラム・レベル、テーブル・レベル、またはパーティション・レベルで変更さ
れたデータの指定量をチェックするスクリプトを作成することができます。
update statistics をいつ実行するかは、datachange 関数、CPU 使用率、テーブ
ルの変更率、パーティションの変更率などによって収集される多数の変数を基
にすることができます。
パーティションでの
datachange を基にした
update statistics の実行
この例では、authors がパーティションで、ユーザは author_ptn2 パーティショ
ン の city カ ラ ムへのデータ変更が 50 パーセント以上のときに、update
statistics を実行します。
select @datachange = datachange("authors","author_ptn2", "city")
if @datachange >= 50
begin
update statistics authors partition author_ptn2(city)
end
go
また、ユーザは、システムのアイドル時または他のパラメータが満たされたと
きに実行されるスクリプトを指定することもできます。
カラムでの datachange
を基にした update
statistics の実行
この例では、authors テーブルの city カラムへのデータ変更が 100 パーセント
以上のときに、ユーザが update statistics をトリガします ( この例でのテーブ
ルはパーティション化されていません )。
select @datachange = datachange("authors",NULL, "city")
if @datachange > 100
begin
update statistics authors (city)
end
go
182
Adaptive Server Enterprise
第7章
パフォーマンス改善のための統計値の使用
カラム統計値と統計値管理
ヒストグラムは、インデックス・ベースではなくカラム・ベースで保持されま
す。これは、統計値管理と次のような関係があります。
•
1 つのカラムが複数のインデックスに使用されている場合、update statistics、
update index statistics、または create index が、カラムのヒストグラムとすべ
てのプレフィクス・サブセットの密度統計値を更新する。
update all statistics は、テーブル内の全カラムのヒストグラムを更新する。
•
インデックスを削除してもインデックスの統計値は削除されない。これ
は、インデックスがなくても、オプティマイザがカラムレベルの統計値を
コストの見積もりに使用できるため。
インデックスの削除後に統計値も削除したい場合は、delete statistics を使
用して明示的に削除する。
統計値がクエリ・プロセッサにとって有益な場合やインデックスなしで統
計値を保持したい場合は、時間の経過とともにキー値の分布が変わるイン
デックスに対して、カラム名を指定して update statistics を使用する。
•
テーブルをトランケートしても sysstatistics のカラムレベルの統計値は
削除されない。多くの場合、テーブルがトランケートされ、同じデータが
再ロードされる。
truncate table はカラムレベルの統計値を削除しないので、データが同じ
場合、テーブルの再ロード後に update statistics を実行する必要はない。
キー値の分布が異なるデータでテーブルを再ロードする場合は、update
statistics を実行する。
•
with statistics 句でステップ数に “0” を指定して create index を実行する
と、インデックスの統計値に影響を与えることなく、そのインデックスを
削除して再作成できる。この create index コマンドは sysstatistics 内の統
計値には影響しない。
create index title_id_ix on titles(title_id)
with statistics using 0 values
これにより、optdiag を使用して編集した統計値を上書きせずに、インデッ
クスを再作成できる。
•
クエリ・プロセッサ
2 人のユーザが同じテーブルの同じカラムで同時にインデックスを作成し
ようとする場合、sysstatistics に重複するキー値を入力することになるた
め、どちらかのコマンドが失敗する可能性がある。
183
カラム統計値の作成と更新
カラム統計値の作成と更新
インデックス未設定カラムに統計値を作成すると、多くのクエリのパフォーマ
ンスが向上します。オプティマイザは、where 句か having 句に指定したあらゆ
るカラムの統計値を使用して、テーブル上のクエリ句の完全なセットに一致す
るロー数を見積もることができます。
また、インデックスのマイナー・カラムや探索引数での使用頻度の高いイン
デックス未設定カラムに統計値を追加すると、オプティマイザの見積もりを改
善できます。
データ修正中に大量のインデックスを管理するには、コストがかかります。
テーブルへの挿入や削除ごとにインデックスを更新する必要があり、さらに更
新によって複数のインデックスが影響を受けます。
インデックスを作成せずにカラムの統計値を生成すると、クエリに読み込まれ
るページ数を見積もるときに、オプティマイザがより多くの情報を使用できま
す。データ修正中のインデックス更新にかかる処理コストも必要ありません。
オプティマイザは、where 句や having 句の探索引数に使用されるカラムや、
ジョイン句に指定されたカラムの統計値を適用できます。
統計値を作成および管理するには、次のコマンドを使用します。
•
update statistics は、カラム名を指定して使用すると、インデックスを作
成せずにカラムの統計値を生成する。
オプティマイザはこれらのカラム統計値を使用し、カラムを参照するクエ
リのコストをより正確に見積もることができる。
•
update index statistics は、インデックス名を指定して使用すると、イン
デックス内の全カラムの統計値を作成または更新する。
テーブル名を指定して使用すると、全インデックス・カラムの統計値を更
新する。
•
update all statistics は、テーブル内の全カラムの統計値を作成または更新
する。
統計値の作成に適しているのは、次のカラムです。
184
•
where 句や having 句で探索引数として頻繁に使用されるカラム。
•
複合インデックスに含まれるカラムで、先行カラムでないが、クエリに
よって返される必要があるデータ・ロー数の見積もりに役立つカラム。
Adaptive Server Enterprise
第7章
パフォーマンス改善のための統計値の使用
統計値の追加が有効な場合
統計値の追加が有効な場合を判断するには、set option コマンド(または set
option コマンド群)および set statistics io on を使用してクエリを実行します。set
option コマンド(または set option コマンド群)によって表示される「返される
ロー」および I/O 見積もりと、statistics io によって表示される実際の I/O の間
に大幅な相違がある場合は、クエリを調べ、統計値の追加により見積もりの正
確さが向上する場所を探します。特に、探索引数とジョイン・カラムにデフォ
ルトの密度値を使っている場所を探します。
また、set option show_missing_stats コマンドは、ヒストグラムを使用したカ
ラムの名前と、複数属性の密度を使用したカラムのグループを出力します。こ
れは、統計値の追加が有用な場所を判断するのに特に便利です。
update statistics を使用したカラムへの統計値の追加
次のコマンドは、title テーブルの price カラムに統計値を追加します。
update statistics titles (price)
次のコマンドは、カラムにヒストグラムのステップ数を指定します。
update statistics titles (price)
using 50 values
次のコマンドは、titles.pub_id カラムにヒストグラムを追加し、
「pub_id」、
「pub_id、pubdate」、「pub_id、pubdate、title_id」というプレフィクス・サブ
セットの密度値を生成します。
update statistics titles(pub_id, pubdate, title_id)
注意 テーブル名を指定して update statistics を実行すると、インデックスに対
してのみ、先行カラムのヒストグラムと密度が更新されます。インデックス未
設定カラムの統計は更新されません。これらの統計値を管理するには、update
statistics を実行してカラム名を指定するか、update all statistics を実行します。
update index statistics を使用したマイナー・カラムへの統計値の追加
インデックス中の全カラムの統計値を作成または更新するには、update index
statistics を使用します。構文は次のとおりです。
update index statistics
table_name [[ partition data_partition_name ] |
[ index_name [ partition index_partition_name ] ] ]
[ using step values ]
[ with consumers = consumers ] [, sampling = percent]
クエリ・プロセッサ
185
ヒストグラムのステップ数の選択
update all statistics を使用した全カラムへの統計値の追加
テーブル上の全カラムの統計値を作成または更新するには、update all statistics
を使用します。構文は次のとおりです。
update all statistics table_name
[partition data_partition_name]
ヒストグラムのステップ数の選択
デフォルトでは、各ヒストグラムのステップ数は 20 です。これは、値が均一
に分布しているカラムの場合、パフォーマンスとモデリングがともに良好にな
るステップ数です。ステップ数を多くすると、次のカラムに対する I/O の見積
もりがより正確になります。
•
重複度の高い値が多いカラム。
•
値の分布が均一でない、または偏りが生じているカラム。
•
ワイルドカードを先行して使用した like クエリの参照先カラム。
注意 データベースをバージョン 11.9 より前のサーバから更新した場合、
distribution page で使用されたステップ数がデフォルトになります。
ステップ数が多すぎる場合のデメリット
ステップ数をクエリ最適化に必要な数以上に増やすと、Adaptive Server のパ
フォーマンスが低下します。これは主に、統計値の保管と使用に必要な領域が
増加するためです。ステップ数を増やすと、次のことが発生します。
•
sysstatistics に必要なディスク記憶領域が増加する。
•
クエリ最適化中の統計値読み込みに必要なキャッシュ領域が増加する。
•
ステップ数が非常に多い場合は、必要な I/O が増加する。
クエリ最適化中、ヒストグラムはプロシージャ・キャッシュから借りた領域を
使用します。この領域は、クエリ最適化が終わりしだい解放されます。
186
Adaptive Server Enterprise
第7章
パフォーマンス改善のための統計値の使用
ステップ数の選択
たとえば、テーブルにローが 5,000 あり、1 つのローだけに一致する値がカラ
ム中に 1 つの場合、各値ごとに頻度セルを含むヒストグラムを得るには 5,000
ステップを要求する必要があります。実際のステップ数は 5,000 ではありませ
ん。異なる値の数に 1 を足したもの ( 密度の高い頻度セルの場合 ) か、値の数
の 2 倍に 1 を足したもの ( まばらな頻度セルの場合 ) になります。
他に注意すべき点として、sp_configure オプションの histogram tuning factor
は、重複度の高い値が多い場合、パラメータ内で自動的により大きなステップ
数を選択します。
update statistics 実行時のスキャン・タイプ、ソートの稼働条件、
ロック
表 7-2 に、update statistics 実行中に実行されるスキャンのタイプ、取得される
ロックのタイプ、およびソートが必要な時期を示します。
表 7-2: update statistics 実行中のスキャン、ソート、ロック
update statistics の指定
実行されるスキャンとソート
ロック
各ノンクラスタード・インデックスのテーブル・ス
キャンとリーフ・レベル・スキャン
レベル 1 ( 現在のページに対する
意図的共有テーブル・ロック、共
有ロック )
テーブル名
全ページロック・
テーブル
データオンリーロック・ 各ノンクラスタード・インデックスと、もしあれば
テーブル
そのクラスタード・インデックスのテーブル・ス
キャンとリーフ・レベル・スキャン
レベル 0 ( ダーティ・リード )
テーブル名とクラスタード・インデックス名
全ページロック・
テーブル
テーブル・スキャン
データオンリーロック・ リーフ・レベル・インデックス・スキャン
テーブル
レベル 1 ( 現在のページに対する
意図的共有テーブル・ロック、共
有ロック )
レベル 0 ( ダーティ・リード )
テーブル名とノンクラスタード・インデックス名
全ページロック・
テーブル
リーフ・レベル・インデックス・スキャン
データオンリーロック・ リーフ・レベル・インデックス・スキャン
テーブル
レベル 1 ( 現在のページに対する
意図的共有テーブル・ロック、共
有ロック )
レベル 0 ( ダーティ・リード )
テーブル名とカラム名
全ページロック・
テーブル
テーブル・スキャン ( ワーク・テーブルを作成して
ワーク・テーブルをソートする )
データオンリーロック・ テーブル・スキャン ( ワーク・テーブルを作成して
テーブル
ワーク・テーブルをソートする )
クエリ・プロセッサ
レベル 1 ( 現在のページに対する
意図的共有テーブル・ロック、共
有ロック )
レベル 0 ( ダーティ・リード )
187
update statistics 実行時のスキャン・タイプ、ソートの稼働条件、ロック
インデックス未設定カラムまたは非先行カラムのソート
イ ン デッ ク ス未 設 定 カ ラ ム と イ ン デ ッ ク ス 内 の 非 先 行 カ ラ ム に 対 し て、
Adaptive Server は逐次テーブル・スキャンを実行します。まず、ワーク・テー
ブルにカラム値をコピーしてから、そのワーク・テーブルをソートしてヒスト
グラムを作成します。with consumers 句が指定されないかぎり、ソートは逐次
実行されます。
並列ソートの設定要件の詳細については、『パフォーマンス&チューニング・
ガイド:オプティマイザと抽象プラン』の「第 9 章 並列ソート」を参照して
ください。
update index statistics 実行時のロック、スキャン、ソート
update index statistics コマンドによって生成される一連の統計更新オペレー
ションでは、同等のインデックス・レベルおよびカラム・レベルのコマンドと
同じロック、スキャン、およびソートが使用されます。たとえば、salesdetail
テーブルの salesdetail(stor_id, ord_num, title_id) にノンクラスタード・イン
デックス sales_det_ix がある場合に、次のコマンドを実行したとします。
update index statistics salesdetail
このコマンドでは、次の update statistics オペレーションが実行されます。
update statistics salesdetail sales_det_ix
update statistics salesdetail (ord_num)
update statistics salesdetail (title_id)
update all statistics 実行時のロック、スキャン、ソート
update all statistics コマンドは、テーブルの各インデックスに対して一連の
update statistics オペレーションを生成し、すべてのインデックス未設定カラ
ムに対して一連の update statistics オペレーションを生成します。
with consumers 句の使用
update statistics の with consumers 句は、RAID デバイス上の分割されたテー
ブルでの使用を意図して設計されています。このデバイスは、Adaptive Server
では単一の I/O デバイスのように見えますが、並列ソートに必要な高いスルー
プットを実現します。詳細については、
『パフォーマンス&チューニング・ガ
イド:オプティマイザと抽象プラン』の「第 9 章 並列ソート」を参照してく
ださい。
188
Adaptive Server Enterprise
第7章
パフォーマンス改善のための統計値の使用
update statistics が同時処理に与える影響を小さくする方法
データオンリーロック・テーブルの場合、update statistics はダーティ・リード
を使用するため ( トランザクションの独立性レベル 0)、サーバ上で他のタスク
がアクティブなときでも実行でき、テーブルやインデックスへのアクセスをブ
ロックしません。インデックス内の先行カラムの場合、統計値の更新にはイン
デックスのリーフレベル・スキャンだけが必要で、ソートは必要ありません。
したがって、カラムの統計値を更新しても同時処理のパフォーマンスにはさほ
ど影響しません。
しかし、インデックス未設定カラムや非先行カラムの統計値を更新する場合
は、テーブル・スキャン、ワーク・テーブル、ソートが必要になり、同時処理
に影響します。
•
ソートは、CPU を集中的に使用する。CPU 使用率を最小化したい場合は、
逐次ソートを使用するか、ワーカー・プロセス数を少なくする。または、
実行クラスを使って update statistics に優先度を設定する。
『パフォーマンス&チューニング・ガイド:基本』の「エンジンと CPU の
使用方法」を参照。
•
ソート実行のマージに必要なキャッシュ領域は、データ・キャッシュから
取られる。さらに、プロシージャ・キャッシュ領域も必要になる。number
of sort buffers を低い値に設定すると、バッファ・キャッシュで使用され
る領域が減少する。
number of sort buffers に大きな値を設定すると、データ・キャッシュから
取る領域が増える。また、ソートされた値のマージにプロシージャ・キャッ
シュ領域が使用されるため、プロシージャ・キャッシュからストアド・プ
ロシージャがフラッシュされる場合もある。
ソートのためのワーク・テーブル作成にも tempdb の領域が使用されます。
クエリ・プロセッサ
189
delete statistics コマンドの使用
delete statistics コマンドの使用
11.9 より前のバージョンの SQL Server と Adaptive Server では、インデックス
を削除するとインデックスのディストリビューション・ページが削除されま
す。バージョン 11.9.2 以降では、カラムレベルの統計値を、ユーザが明示的に
管理します。オプティマイザは、インデックスが存在しない場合でもカラムレ
ベルの統計値を使用できます。delete statistics コマンドを使用すると、特定の
カラムの統計値を削除できます。
作成したインデックスがデータ・アクセスに有用でない、またはデータ修正時
のインデックス管理にコストがかかるという理由で、後からインデックスを削
除する場合、次のことを確認してください。
•
インデックスの統計値がオプティマイザにとって有益かどうか。
•
対象とするインデックスでカラムのキー値の分布が、ローの挿入と削除に
よって時間とともに変わることが多いかどうか。
キー値の分布が変わる場合、update statistics を定期的に実行して統計値
を有益なものに保つ必要がある。
次の例では、titles テーブルの price カラムの統計値を削除します。
delete statistics titles(price)
注意 delete statistics をテーブル名を指定して使用すると、インデックスがあ
る場合でもテーブルのすべての統計値が削除されます。
インデックスの統計値をリストアするには、テーブルで update statistics を実
行します。
190
Adaptive Server Enterprise
第7章
パフォーマンス改善のための統計値の使用
ロー・カウントが不正確な場合
特にクエリ処理にロールバック・コマンドが多い場合、ロー数、転送された
ロー数、削除されたロー数のロー・カウント値が不正確になることがありま
す。作業負荷が極端に大きく、ハウスキーピング・ウォッシュ・タスクがあま
り実行されない場合、これらの統計値はさらに不正確になる傾向があります。
update statistics を実行すると、systabstats 内のこれらのカウントが訂正され
ます。
dbcc checktable または dbcc checkdb を実行すると、メモリ内の統計値が更新
されます。
ハウスキーピング・ウォッシュ・タスクや sp_flushstats を実行すると、これ
らの値は systabstats に保管されます。
注意 ハウスキーピング統計値のフラッシュを有効にするには、設定パラメー
タ housekeeper free write percent を 1 以上に設定してください。
クエリ・プロセッサ
191
ロー・カウントが不正確な場合
192
Adaptive Server Enterprise
付 録
A
抽象プランの仕様
ここで説明するオペレータが Adaptive Server 15.0 の抽象プランに追加さ
れました。
delete
説明
子 derived_table で delete オペレータの位置を指定する。
構文
( delete derived_table )
パラメータ
derived_table
削除するローを修飾する子抽出テーブル。
例
インデックス・スキャンによって削除するローを修飾する。
delete t where t1>0
plan
"( delete
( i_scan it1 t )
)"
使用法
参照
クエリ・プロセッサ
•
delete の結果に対応する抽出テーブルを返す。
•
クエリは、delete 文の一部である必要がある。
•
delete は、ルートに delete Lava オペレータを含まないプランにのみ
便利である。たとえば、部分的な抽象プラン "(i_scan it1 t)" を
使用して、例 1 と同じ結果を得ることができる。
•
通常、delete SQL 文は、役に立つ抽出テーブルを返さない。代わり
に、その結果によって、結果テーブルに変更が行われる。しかし、抽
象プラン・オペレータのツリーはクエリ実行プラン・オペレータのツ
リーに一致する必要があるため、クエリ実行プランで delete オペレー
ションの親も記述する抽象プランを使用する必要がある場合は、
delete を使用する。
•
コマンド
insert、update
193
distinct
distinct
説明
子 derived_table で distinct オペレータの 1 つの位置を指定する。distinct は、ク
エリのセマンティックに応じて重複を削除する。
構文
( distinct derived_table )
パラメータ
derived_table
重複を削除する子抽出テーブル。
例
例 1 排他相関値を取得することによって存在サブクエリの重複セマンティッ
クを実行し、クエリ・プロセッサが distinct、scan、join の最適な物理オペレー
タを選択するようにする。
select * from t
where t1 in
(select r1 from r, s where r2=s2)
plan
"( join
(distinct
(join
(scan r)
(scan s)
)
)
(scan t)
)"
例 2 排他性を評価する前に、テーブル r、s、および t のジョインを実行する。
これは「遅延型評価」の例で、ある状況において役立つ。このクエリは、クエ
リ・プロセッサが distinct、scan、join の最適なコストベースの物理オペレー
タを選択するようにする。
create view dv(dv1, dv2)
as
select distinct r1, s1
from r, s
where r2=s2
select * from t, dv where t1=dv1
plan
"(distinct
(join
(join
(scan t)
(scan r)
)
(scan s)
)
)"
194
Adaptive Server Enterprise
付録 A
使用法
抽象プランの仕様
•
返された値は、抽出テーブルで distinct が実行されたことを示す。
•
クエリが重複演算子を削除し、そのクエリにジョインが含まれている場
合、クエリ・プロセッサは十分早い時期に排他性を評価できるため、ジョ
インされる結果セットのサイズを減らすことができる。しかし、ジョイン
で結果セットを減らす場合、クエリ評価の遅い時期に排他評価を実行する
方がよい場合がある。クエリで排他性を評価する時期を早くするか遅くす
るかは、distinct、in、または exists タイプのサブクエリを使用したビュー
を含むクエリにおいて、特に重要である。
•
排他の実行は、子 derived_table で必要であり、実行可能である必要がある。
•
クエリでは、select distinct または exists/in サブクエリで重複
を削除する必要がある。
•
distinct オペレータは、distinct キーに応じて重複を削除する。クエリ・プ
ロセッサは、distinct オペレータの位置とクエリのセマンティックに応じ
て、distinct キーを計算する。
•
クエリ・プロセッサは、排他が可能かどうか、および必要かどうかを確認
する。それが正当である場合のみ、クエリ・プロセッサは抽象プランの
distinct オペレータを適用する。そうでない場合、このオペレータとルー
トまでのすべての親は効果的ではない。
•
distinct クエリ実行プラン・オペレータは存在しない。distinct 抽象プラ
ン・オペレータを使用すると、クエリ・プロセッサは DistinctHashing、
DistinctSorted、および DistinctSorting などの使用可能な排他実装におい
てコストを評価する。
•
排他を実行する必要がある場合、常に distinct オペレータが必要なわけで
はない。いくつかの状況では、クエリ・プロセッサは semijoin を使用し
て排他を実行できる。
•
distinct 抽象プラン・オペレータは、ワーク・テーブルを暗黙的には使用
しない。いくつかの排他アルゴリズム ( たとえば DistinctSorted) では、
ワーク・テーブルを使用しない。ワーク・テーブルを使用するアルゴリズ
ムでは、ワーク・テーブルは演算子に隠されている。ワーク・テーブルと
2 つの処理ステップがクエリ実行プランによって常に使用されている場
合のこの動作は、前のリリースから変更されている。
•
前のバージョンの Adaptive Server では、ワーク・テーブルと 2 つの処理ス
テップは抽象プランによって常に公開されていた。前のバージョンの
Adaptive Server では、例 2 の抽象プランは次のようになっていた。
(plan
(store (work_t Worktable1)
(nl_join
(t_scan r)
(i_scan is2 s)
)
(nl_join
(t_scan (work_t Worktable1))
クエリ・プロセッサ
195
distinct
(i_scan it1 t)
)
)
参照
196
•
これと同等の Adaptive Server 15.0 抽象プランは、ストアの子において、
ワーク・テーブルのスキャンを distinct 抽象プラン・オペレータに置き換
えることによって取得できる。
•
コマンド
distinct_hashing、distinct_sorted、distinct_sorting
Adaptive Server Enterprise
付録 A
抽象プランの仕様
distinct_hashing
説明
子 derived_table で DistinctHashing オペレータの位置を指定する。クエリのセ
マンティックに応じて重複を削除する。
構文
(distinct_hashing derived_table )
パラメータ
derived_table
重複の削除を行う子抽出テーブル。
例
例 1 ハッシュ排他相関値を取得することによって、存在サブクエリの重複セマ
ンティックを実行する。これによって、クエリ・プロセッサはスキャンとジョ
インのために最適なコストベースの物理オペレータを選択する。
select * from t
where t1 in
(select r1 from r, s where r2=s2)
plan
"( join
(distinct_hashing
(join
(scan r)
(scan s)
)
)
(scan t)
)"
例 2 テーブル r、s、および t でジョインを実行し、ハッシュベースの distinct
演算を使用して排他を実行し、クエリ・プロセッサは scan および join のため
に最適なコストベースの物理オペレータを選択する。このプランは、存在ジョ
インが通常の内部ジョインに変換され、その後に重複の削除が行われていた以
前の Adaptive Server リリースの方法を一般化する。
create view dv(dv1, dv2)
as
select distinct r1, s1
from r, s
where r2=s2
select * from t, dv where t1=dv1
plan
"(distinct_hashing
(join
(join
(scan t)
(scan r)
)
(scan s)
)
)"
クエリ・プロセッサ
197
distinct_hashing
使用法
参照
198
•
返された値は、抽出テーブルで排他が実行されたことを示す。
•
排他の実行は、子 derived_table で必要であり、実行可能である必要がある。
•
ハッシュベースの排他の実行は、CPU と I/O コストにおいて、ソートベー
スの distinct 評価よりもコストが低い。
•
distinct_hashing には、順序付けが関連する前提条件がないという利点が
ある。
•
抽象プランの排他実行については、distinct 抽象プラン・オペレータでよ
り詳しく説明する。
•
コマンド
distinct_sorted、distinct_sorting
Adaptive Server Enterprise
付録 A
抽象プランの仕様
distinct_sorted
説明
子 derived_table で DistinctSorted オペレータの位置を指定する。クエリのセマ
ンティックに応じて重複を削除する。
構文
( distinct derived_table )
パラメータ
derived_table
重複が削除される子抽出テーブル。
例
例 1 排他相関値を取得することによって、存在サブクエリの重複セマンティッ
クを実行し、重複を実行中に削除する。この例では、クエリ・プロセッサは、
コストベースの評価に応じて scan および join のいくつかに対して最適な物理
オペレータを選択する。しかし、distinct キーの順序付けは、インデックス・
スキャンとネストループ・ジョインを実行することによって行われる。これ
は、前のバージョンの Adaptive Server のロー・フィルタリング方法を一般化し
たものである。
select * from t
where t1 in
(select r1 from r, s where r2=s2)
plan
"( join
(distinct_sorted
(nl_join
(i_scan ir1 r)
(scan s)
)
)
(scan t)
)"
例 2 この抽象プランは、distinct ビュー射影の実行中に重複を削除する。この
アプリケーションは、少なくとも (r1,r2) で順序付けを提供する r-s join サブプ
ランが存在する場合に成功する。
create view dv(dv1, dv2)
as
select distinct r1, r2
from r, s
where r2=s2
select * from t, dv where t1=dv1
plan
"( join
(distinct_sorted
(join
(scan r)
(scan s)
)
)
(scan t)
)"
クエリ・プロセッサ
199
distinct_sorted
使用法
参照
200
•
戻り値は、排他値を含む抽出テーブルである。
•
排他の実行は、子 derived_table で必要であり、実行可能である必要がある。
•
子 derived_table は、distinct キーによって順序付けされる。
•
使用可能な順序付けベースの、実行中における排他実行は、一番コストの
低い、ゼロコストのソリューションである。
•
distinct_sorted は、前のバージョンの Adaptive Server のロー・フィルタリ
ングに似ている。
•
distinct_sorted では、順序付けする distinct キーが必要である。さまざま
な排他実行シナリオにおいて、クエリ・プロセッサが排他キーを判断する
のが難しい場合がある。いくつかの場合、ベース・テーブルのロー ID (RID)
が使用されるが、そのような順序付けは順序付けベースのインデックス和
集合のみに使用可能である。
•
このオペレータが正当でない場合、このオペレータと抽象プランのルート
までのすべての親は効果的ではない。
•
抽象プランの排他実行については、distinct 抽象プラン・オペレータでよ
り詳しく説明する。
•
コマンド
distinct、distinct_hashing、distinct_sorting
Adaptive Server Enterprise
付録 A
抽象プランの仕様
distinct_sorting
説明
子 derived_table で DistinctSorting オペレータの位置を指定する。クエリのセマ
ンティックに応じて重複を削除する。
構文
(distinct_sorting derived_table )
パラメータ
derived_table
重複が削除される子 derived_table。
例
例 1 ソートベースの排他相関値を取得することによって、存在サブクエリの重
複セマンティックを実行する。この例では、クエリ・プロセッサはスキャンと
ジョインのために最適なコストベースの物理オペレータを選択する。排他の実
行時に取得された順序付けは、order by 句に役に立つもので、クエリ・プロ
セッサは、順序付けを保持するネストループ・ジョインまたはマージ・ジョイ
ンを最適なプランとして選択する。それ以外の場合は、distinct_hashing がよ
り最適なプランを提供する。
select * from t
where t1 in
(select r1 from r, s where r2=s2)
order by t1
plan
"( join
(distinct_sorting
(join
(scan r)
(scan s)
)
)
(scan t)
)"
例 2 テーブル r、s、および t をジョインし、値が排他的であるかどうかを評価
する。これは、排他の「遅延型」評価の例である。これによって、クエリ・プ
ロセッサはスキャンとジョインのために最適なコストベースの物理オペレー
タを選択する。排他キーは t.RID で、これはテーブル t のロー ID を計算する隠
しカラムである。このような場合、distinct_hashing ベースのプランの方が速
い可能性が高い。
create view dv(dv1, dv2)
as
select distinct r1, s1
from r, s
where r2=s2
select * from t, dv where t1=dv1
plan
"(distinct_sorting
join
(join
(scan t)
(scan r)
クエリ・プロセッサ
201
distinct_sorting
)
(scan s)
)
)"
使用法
参照
202
•
戻り値は、排他値を含む抽出テーブルである。
•
排他値の実行は、子 derived_table で必要であり、実行可能である必要が
ある。
•
ソートベースの排他の実行は、最もコストの高いソリューションである。
•
distinct_sorting は、distinct キーで順序付けされる結果を作成する。最適
なプランにこの順序付けが必要な場合、そのようなプランに追加コストは
かからない ( たとえば、sort の追加コストを払わずに上位にマージ・ジョ
インを配置する )。
•
ソート・キーが親にとって役に立たない場合、distinct_hashing はより最
適なプランを生成する。
•
コマンド
distinct、distinct_hashing、distinct_sorting
Adaptive Server Enterprise
付録 A
抽象プランの仕様
enforce
説明
必要なすべてのプロパティを実行する。
構文
( enforce derived_table )
パラメータ
derived_table
プロパティを実行する子抽出テーブル。
例
このプランは、マージ・ジョインを使用して、テーブル s と r のジョイン順を
設定し、子の順序と分割が正当であることを保証する。
select r1, s1 from r, s where r2=s2
plan
"(m_join
(enforce
(scan s)
)
(enforce
(scan r)
)
)"
使用法
参照
クエリ・プロセッサ
•
戻り値は、すべてのオペレータにおいて正当であると保証された、実行対
象の抽出テーブルである。
•
子 (enforce …) を使用することによって、いずれのオペレータも実行
可能な前提条件を満たすことができる。
•
演算子がクエリ内で意味的に不正な場合、enforce は実行されない。
•
子がすでに必要なすべての実行可能プロパティを提供している場合、
enforce 抽象プラン・オペレータは子抽出テーブルを返す。
•
通常、enforce 抽象プラン・オペレータは、コストの高いオペレータであ
る。このオペレータは、子に sort または xchg オペレータを追加する。
enforce を使用して、クエリ・プロセッサが不足しているプロパティを基
にした抽象プランを拒否するかどうかを確認する。sort または xchg を使
用して、必要なプロパティを明示的に実行することを推奨する。
•
コマンド
sort、xchg、rep_xchg
203
group
group
説明
子抽出テーブルで group オペレータの位置を指定する。
構文
( group derived_table )
パラメータ
derived_table
グループ化される子抽出テーブル。
例
例 1 t のインデックス・スキャンでグループ化する。
select t1, sum(t2) from t group by t1
plan
"(group
(i_scan it1 t)
)"
例 2 グループの結果はジョインの外側にあり、
内側にはジョイン属性における
インデックス・スキャンがある。
create view gv(gv1, gv2)
as
select t1, sum(t2) from t group by t1
select * from s, gv where gv1=s1
plan
"(join
(group
(scan t)
)
(i_scan is1 s)
)"
使用法
204
•
戻り値は、グループ化された抽出テーブルである。
•
クエリのセマンティックでは、グループ化を実行する必要がある。
•
クエリには、group by 句が含まれている必要がある。
•
グループ化は、日和見的に実行されるものではない。group 抽象プラン・
オペレータは、クエリ内でグループ化されたテーブルの完全なセットでの
み正当であり、group by を含む関係式の from 句にある。
•
グループ化が必要な場合は、group を使用しなければならない。
•
group としてのクエリ実行プラン・オペレータはなく、抽象プラン group オ
ペレータのみがある。group 抽象プラン・オペレータを使用すると、クエリ・
プロセッサは GroupHashing および GroupSorted などの使用可能なグループ
化実装において、コストベースとプロパティベースの選択を行う。
•
GroupInserting と呼ばれる前バージョンの Adaptive Server のグループ化ア
ルゴリズムは、Adaptive Server 15.0 ではサポートされていない。
•
group 抽象プラン・オペレータは、ワーク・テーブルを暗黙的には使用し
ない。
Adaptive Server Enterprise
付録 A
•
抽象プランの仕様
前のバージョンの処理では、ワーク・テーブルと 2 つの処理ステップは抽
象プランによって常に公開されていた。例 1 では、前のバージョンの抽象
プランは次のようになっていた。
(plan
(store (work_t Worktable1)
(i_scan it1 t)
)
(t_scan (work_t Worktable1)
)
参照
クエリ・プロセッサ
•
15.0 のグループ化抽象プランは、ストアの子においてワーク・テーブルの
スキャンを group 抽象プラン・オペレータに置き換えることによって取得
できる。(plan …) に 1 つの子しか含まれていない場合、その子は完全
に削除される。
•
コマンド
group_sorted、group_hashing
205
group_hashing
group_hashing
説明
子抽出テーブルで GroupHashing オペレータの位置を指定する。
構文
( group_hashing derived_table )
パラメータ
derived_table
グループ化される子抽出テーブル。
例
例 1 グループ化は、t のテーブル・スキャンでハッシュ・アルゴリズムを使用
して実行される。
select t1, sum(t2) from t group by t1
plan
"(group_hashing
(t_scan t)
)"
例 2 グループ化は、ハッシュ・アルゴリズムを使用して実行される。グループ
の結果はジョインの外側にあり、内側にはジョイン属性におけるインデック
ス・スキャンがある。
create view gv(gv1, gv2)
as
select t1, sum(t2) from t group by t1
select * from s, gv where gv1=s1
plan
"(join
group_hashing
(scan t)
)
(i_scan is1 s)
)"
使用法
参照
206
•
戻り値は、グループ化された抽出テーブルである。
•
クエリのセマンティックでは、グループ化を実行する必要がある。
•
group_hashing では、グループ化カラムでの順序付けは必要ない。
•
コマンド
group、group_sorted
Adaptive Server Enterprise
付録 A
抽象プランの仕様
group_sorted
説明
子抽出テーブルで GroupSorted オペレータの位置を指定する。
構文
( group_sorted derived_table )
パラメータ
derived_table
グループ化される子抽出テーブル。
例
例 1 グループ化は、t のインデックス・スキャンで実行中アルゴリズムを使用
して実行され、group by カラムの t1 で必要な順序付けを提供する。
select t1, sum(t2) from t group by t1
plan
"(group_sorted
(i_scan it1 t)
)"
例 2 t のインデックス・スキャンの順序付けされた結果で、実行中グループ化
を実行する。グループの結果はマージ・ジョインの外側にあり、グループ化カ
ラムは等価ジョイン属性である。ジョインの内側は、s1 等価ジョイン属性の
順序付けを提供するインデックス・スキャンである。グループ化は、グループ
化カラム t1 での子の順序付けを保持し、マージ・ジョインが正当であること
を保証する。
create view gv(gv1, gv2)
as
select t1, sum(t2) from t group by t1
select * from s, gv where gv1=s1
plan
"(m_join
(group_sorted
(i_scan it1 t)
)
(i_scan is1 s)
)"
例 3 この抽象プランは例 2 のプランとよく似ているが、クエリ・プロセッサは
scan と join 演算子を選択する。抽象プランは、グループ化カラム t1 で始まる t の
インデックスを使用する場合にのみ正当となる。そのようなインデックスが使用
できない場合、それより上にある group_sorted と join は効果的ではない。
select * from s, gv where gv1=s1
plan
"(join
(group_sorted
(scan t)
)
(scan s)
)"
クエリ・プロセッサ
207
group_sorted
使用法
参照
208
•
戻り値は、グループ化された抽出テーブルである。
•
クエリのセマンティックでは、グループ化を実行する必要がある。
•
子抽出テーブルは、グループ化カラムで順序付けされる。
•
必要な順序付けが可能な場合、実行中グループ化オペレータは最もコスト
の低いソリューションである。
•
group_sorted は前のバージョンの compute 句に似ているが、order by 句
を必要としない。クエリ・プロセッサは、必要な順序付けが使用可能かど
うかを確認する。
•
順序付けの前提条件は、distinct_sorted のものよりもシンプルである。子
は、group by のすべてのカラムで、任意の順序で順序付けされる必要が
ある。
•
group_sorted が正当でない場合、このオペレータと抽象プランのルート
までのすべての親は効果的ではない。
•
コマンド
group、group_hashing
Adaptive Server Enterprise
付録 A
抽象プランの仕様
h_join
説明
ジョインがハッシュ・ジョイン・アルゴリズムを使用して実行されるように指
定する。
構文
( h_join derived_table1 derived_table2 )
パラメータ
derived_table_1, derived_table_2
子抽出テーブル。derived_table1 は外部テーブル、derived_table2 は内部テー
ブルである。
例
例 1 ハッシュ・ジョインを使用して、2 つのテーブル r と s をジョインし、テー
ブル r と s のスキャンでハッシュ・ジョインを実行する。クエリ・プロセッサ
は、テーブル r と s のスキャンに最適な方法を選択する。
select * f
rom r, s where r1 = s1
plan
“ (h_join (scan r) (scan s))”
例 2 ハッシュ・ジョインを使用したグループ化集合を含む 2 つのテーブルで
ジョインを実行する。
create view v(v1, v2) as select s1, sum(s2) from s group by s1
select * from r,v, where r1 = v2
plan
“(h_join)
(scan r)
(group_hashing
(scan s)
)
)”
使用法
参照
クエリ・プロセッサ
•
戻り値は、ジョインされた抽出テーブルである。
•
ハッシュ・ジョインの結果は、データ・ローの順序付けを提供しない。
•
クエリには、等価ジョインが含まれている必要がある。
•
外部ジョインとセミジョインで、ハッシュ・ジョインを使用することもで
きる。
•
h_join では、その入力抽出テーブルにおいて順序付け条件を必要としない。
nl_join、m_join、peer1、peer2
209
h_union_distinct
h_union_distinct
説明
ハッシュベースの方法を使用して重複を削除する union を実行する
HashUnionDistinct オペレータの位置を指定する。
構文
( h_union_distinct derived_table...)
パラメータ
derived_table
union クエリの両側に対応する抽出テーブルを指定する。
例
例 1 このプランは、テーブル・スキャンでハッシュを実行することによって
union の重複値を削除する。
select t1 from t
union
select s1 from s
plan
“(h_union_distinct
(t_scan t)
(t_scan s)
)”
例 2 このプランは、テーブル・スキャンでハッシュを実行することによって
union の重複値を削除する。ハッシュベースの union では、順序付けは必要と
しない。
create view uv(uv1, uv2)
as
select r1, r2 from r
union
select s1, s2 from s
select * from t, uv where t1=uv1
plan
"(h_join
(t_scan t)
(h_union_distinct
(t_scan r)
(t_scan s)
)
)
)"
使用法
210
•
戻り値は、union 抽出テーブルである。
•
クエリのセマンティックでは、重複を削除する union が必要である。
•
クエリには、union [distinct] が含まれている必要がある。
•
h_union_distinct は、union [distinct] オペレータの代替である。これは、
ハッシュを使用して重複を削除する。
•
h_union_distinct は、子に射影全体で一致する順序付けがない場合に、一
番コストの低い union [distinct] オペレータとなる。
Adaptive Server Enterprise
付録 A
参照
クエリ・プロセッサ
抽象プランの仕様
•
一致する順序付けの詳細については、m_union_distinct を参照。
•
AppendUnionAll の後の DistinctSorting を基にした union [distinct] 処理は今後
動作しない。子が順序付けされる場合は、MergeUnionDistinct が最適なアル
ゴリズムになる。それ以外の場合、union の前にそれぞれの子をソートして、
親の順序付けも保持する MergeUnionDistinct を実行する方がコストが低く
なる。親を順序付けする必要がない場合は、HashUnionDistinct が最適なア
ルゴリズムになる。
•
h_union_distinct は、union [distinct] にのみ正当である。クエリ・プロセッ
サは、重複ローを保持する必要のある union all ではそれを拒否する。
union、h_union_distinct、m_union_all
211
hints
hints
説明
関連のない抽象プランの部分同士をバインドする。
構文
(insert derived_table...)
パラメータ
derived_table
子抽出テーブル。
例
これは反例である。このような方法で hints 抽象プラン・オペレータを使用し
ない。このプランは、r、s、および t にこれらのインデックスを使用し、u に
関して、内側に t を持つネストループ・ジョインの外側以外の任意の場所に、
r と s を配置するように述べているようである。しかし、これは、3 つのイン
デックス・スキャンが実行される場合にのみ成功する。hints の親 nl_join は効
果的ではない。
select * from r, s, t, u where r1=s1 and s2=t2 and
s3=u3
plan
“(nl_join
(hints
(I_scan ir1 r)
(I_scan is1 s)
)
(I_scan it2 t)
)”
使用法
212
ヒントの親、および抽象プラン式のルートの全抽象プラン・オペレータは効果
的ではない。
Adaptive Server Enterprise
付録 A
抽象プランの仕様
insert
説明
子抽出テーブルで insert 文の位置を指定する。
構文
( insert derived_table )
パラメータ
derived_table
挿入する新しいローを提供する子抽出テーブル。
例
インデックス・スキャンは、挿入されるローを提供する。
insert s
select * from t where t1>0
plan
"( insert
( i_scan it1 t )
)"
使用法
参照
クエリ・プロセッサ
•
戻り値は、insert の結果に対応する抽出テーブルである。
•
クエリは、insert 文の一部である必要がある。
•
insert 抽象プラン・オペレータは、ルートに insert Lava オペレータを含ま
ないプランにのみ便利である。
•
通常、insert SQL 文は、役に立つ抽出テーブルを返さない。代わりに、そ
の結果によって、結果テーブルに変更が行われる。しかし、抽象プラン・
オペレータのツリーはクエリ実行プラン・オペレータのツリーに一致する
ため、クエリ実行プランで insert の親も記述する抽象プランが必要な場合
は、抽象プラン insert オペレータを使用する必要がある。
•
コマンド
delete、update
213
join
join
説明
ジョイン・アルゴリズム ( たとえばネストループ・ジョイン、マージ・ジョイ
ン、ハッシュ・ジョイン ) を指定せずに、2 つ以上の抽象プランの抽出テーブ
ルでジョインを指定する。
構文
( join derived_table1 derived_table2 )
パラメータ
derived_table
ジョインされる抽象プランの抽出テーブル。
例
t1 は外部テーブルで、t2 は内部テーブルである。抽象プランは t1 ではテーブ
ル・スキャンを使用するが、テーブル t2 では最適なスキャン方法を選択する。
クエリ・プロセッサは、ジョイン・オペレーションを選択する。
select * from t1, t2
where c21 = 0 and c11 = c22
plan
"(join (t_scan t1) (scan t2))"
使用法
•
join は、すべてのバイナリ・ジョイン ( 内部ジョイン、外部ジョイン、ま
たはセミジョイン ) を記述する一般的な論理オペレータである。
•
Adaptive Server が生成した抽象プランでは、実際のジョイン・アルゴリズ
ムを示すために、join の代わりに、nl_join、m_join、または h_join オペ
レータが使用される。
•
join 構文は、複数のテーブルに関連するジョインを記述するための省略形
を提供する。次に構文を示す。
(join
(scan
(scan
(scan
.............
(scan
(scan
)
t1)
t2)
t3)
tN-1)
tN)
上記は、次の構文の省略形である。
(join
(join
......
(join
(join
(scan t1)
(scan t2)
)
(scan t3)
)
.......
(scan tN-1)
)
214
Adaptive Server Enterprise
付録 A
抽象プランの仕様
(scan tN)
)
参照
クエリ・プロセッサ
•
テーブルは、抽象プランで指定したツリー構造を使用してジョインされる。
•
コマンド
peer1、peer2
215
m_join
m_join
説明
指定した抽象プランの抽出テーブル間で実行されたマージ・ジョインの結果で
ある抽象プランの抽出テーブル。
構文
( m_join derived_table_1 derived_table_2 )
パラメータ
derived_table
ジョインされる抽象プランの抽出テーブル。derivied_table_1 は外部テーブ
ルで、derived_table_2 は内部テーブルである。
例
例 1 テーブル t1 と t3 のマージ・ジョインを指定し、次にテーブル t2 とのネス
トループ・ジョインを指定する。
select t1.c11, t2, c21
from t1, t2, t3
where t1.c11 = t2.c21
and t1.c11 = t3.c31
plan
"(nl_join
(m_join
(i_scan i_c31 t3)
(i_scan i_c11 t1)
)
(i_scan i_c21 t2)
)"
例 2 t1 のテーブル・スキャン中にソートが必要なマージ・ジョインを指定す
ることによって、クエリ・プロセッサはマージ・ジョインを実行できる。
select * from t1, t2, t3
where t1.c11 = t2.c21 and t1.c11 = t3.c31
and t2.c22 = 7
plan
"(nl_join
(m_join
(i_scan i_c21 t2)
(sort
(t_scan t1)
)
)
(i_scan i_c31 t3)
)"
例 3 テーブル t2 と t3 のスキャンは、マージ・ジョインの正しい順序付けを行う
ためにソートされる。マージ・ジョインが実行されると、このマージ・ジョイ
ンでソートされるテーブル t1 は、マージ・ジョインで正しく順序付けされる。
select * from t1, t2, t3
where c11 = c23 and c13 = c23
plan
"(m_join
(sort
(t_scan t1)
216
Adaptive Server Enterprise
付録 A
抽象プランの仕様
(m_join
(sort
(t_scan t2)
)
(sort
(t_scan t3)
)
)
)"
使用法
参照
クエリ・プロセッサ
•
m_join 句にあるテーブルは、指定したツリー構造を使用してジョインさ
れる。
•
マージ・ジョインで必要な順序付けが子で使用できない場合、明示的に sort
オペレータを指定して順序付けを行う必要がある ( 例 2 と例 3 を参照 )。
•
m_join オペレータが、マージ・ジョインとして実行できないジョインを
指定するのに使用された場合は無視される。
•
コマンド
join、nl_join、h_join
217
m_union_all
m_union_all
説明
マージ・アルゴリズムを使用して union all を発行する MergeUnionAll オペレー
タの位置を指定する。m_union_all オペレータは、子抽出テーブルの順序付け
を保持する。
構文
( m_union_all derived_table … )
パラメータ
derived_table
union でジョインされる抽象プランの抽出テーブル。
例
例 1 このプランは、インデックス・スキャンによって生成される順序付けで、
MergeUnionAll オペレータを保持する順序付けを使用して、order by 句に必要
な順序付けを提供する。
select t1 from t
union all
select s1 from s
order by 1
plan
"(m_union_all
(i_scan it1
(i_scan is1
)"
where t1>0
where s1>0
t)
s)
例 2 インデックス・スキャンによって生成される順序付けで、MergeUnionAll
オペレータを保持する順序付けを使用して、マージ・ジョインに必要な順序付
けを提供する。
create view uv(uv1, uv2)
as
select r1, r2 from r
union all
select s1, s2 from s
select * from t, uv where t1=uv1
plan
"(m_join
(i_scan it1 t)
(m_union_all
(i_scan ir1 r)
(i_scan is1 s)
)
)"
使用法
218
•
戻り値は、union 抽出テーブルである。
•
クエリのセマンティックでは、重複を保持する union が必要である。
•
クエリには、union all が含まれている必要がある。
•
m_union_all は union all オペレータの代替であり、順序付けされた子を
マージして、順序付けされた結果を生成する。
Adaptive Server Enterprise
付録 A
参照
クエリ・プロセッサ
抽象プランの仕様
•
m_union_all では、union all を処理するための順序付けは不要である。
m_union_all の利点は、親 union で順序付けが必要な場合に、使用可能
な順序付けを伝達することである。
•
m_union_all は、union all にのみ正当である。クエリ・プロセッサは、重
複ローを拒否する必要のある union [distinct] ではそれを拒否する。
•
コマンド
union、union_all、m_union_distinct
219
m_union_distinct
m_union_distinct
説明
MergeUnionDistinct オペレータの位置を指定する。m_union_distinct オペレー
タは、マージベースのアルゴリズムを使用して結果セットの重複値を削除する
ことによって、SQL union オペレーションを実行する。
構文
( m_union_distinct derived_table … )
パラメータ
derived_table
union all クエリの両側を占める抽出テーブル。
例
例 1 このプランは、インデックス・スキャンによって生成される順序付けで、
m_union_distinct オペレータを保持する順序付けを使用して、order by の順序
付けを提供する。
select t1 from t where t1>0
union
select s1 from s where s1>0
order by 1
plan
"(m_union_distinct
(i_scan it1 t)
(i_scan is1 s)
)"
例 2 このプランは、r(r1, r2) と s(s1, s2) でのインデックス・スキャン
によって生成される順序付けで、m_union_distinct オペレータを保持する順序
付けを使用して、マージ・ジョインに必要な順序付けを提供する。
create view uv(uv1, uv2)
as
select r1, r2 from r
union
select s1, s2 from s
select * from t, uv where t1=uv1
plan
"(m_join
(i_scan it1 t)
(m_union_distinct
(i_scan ir12 r)
(i_scan is12 s)
)
)"
使用法
220
•
戻り値は、union 抽出テーブルである。
•
クエリのセマンティックでは、重複を削除する union が必要である。
•
すべての子が、互換性のある順序付けを含む必要がある。
•
クエリには、union [distinct] が含まれている必要がある。
•
m_union_distinct は union [distinct] オペレータの代替であり、順序付けさ
れた子をマージして、重複値を動的に削除し、順序付けされた結果を生成
する。
Adaptive Server Enterprise
付録 A
抽象プランの仕様
•
m_union_distinct は、すべての子が射影全体で一致する順序付けを持つ場
合に、一番コストの低い union [distinct] オペレータとなる。
•
一致とは、各 union 側 select リストの位置的に対応するカラムが、メジャー
とマイナーが混合する順序付けと同じ位置にあることを意味する。
たとえば、インデックス r(r1, r2) と s(s1, s2) は共に混合順序付け
を提供するので、例 2 は正しい。なぜなら、すべての側の最初の union カ
ラムである r1 と s1 は共にメジャー属性であり、2 番目の r2 と s2 は共に
マイナー属性だからである。
参照
クエリ・プロセッサ
•
前のバージョンの Adaptive Server では、
AppendUnionAll の後の DistinctSorting
を基にした union [distinct] を提供していたが、これは今後動作しない。子が
順序付けされる場合は、m_union_distinct が最適なアルゴリズムである。そ
れ以外の場合、union の前にそれぞれの子をソートして、次に親の順序付け
も保持する m_union_distinct を実行する方がコストが低くなる。親を順序付
けする必要がない場合は、HashUnionDistinct が最適なアルゴリズムである。
•
このオペレータは、union [distinct] にのみ正当である。クエリ・プロセッ
サは、重複ローを保持する必要のある union all ではそれを拒否する。
•
コマンド
union、h_union_distinct、m_union_all
221
nl_join
nl_join
説明
2 つ以上の抽象プランの抽出テーブルにネストループ・ジョインを指定する。
構文
(nl_join derived_table_1, derived_table_2)
パラメータ
derived_table
ジョインされる抽象プランの抽出テーブル。
例
例 1 外部テーブルとしてテーブル t2、内部テーブルとしてテーブル t1 のジョ
イン順を使用する。
select * from t1, t2
where c21 = 0 and c22 = c12
plan
“(nl_join
(i_scan i_c21 t2)
(i_scan i_c12 t1)
)”
例 2 テーブル t2 を t1 とジョインし、
抽象プランの抽出テーブルは t3 とジョイ
ンされる。
select * from t1, t2
where c21 = 0
and c22 = c12
and c11 = c31
plan
“(nl_join
(i_scan i_c21 t2)
(i_scan i_c12 t1)
(i_scan i_c31 t3)
)”
使用法
•
nl_join オペレータは、すべてのバイナリ・ジョイン ( 内部ジョイン、外部
ジョイン、またはセミジョイン ) を記述するジョイン・オペレータである。
ジョインは、ネストループ・クエリの実行方法を使用して実行される。
•
テーブルは、nl_join 句で指定した順序でジョインされる。
•
nl_join 構文は、複数のテーブルに関連するジョインを記述するための省略
形を提供する。次に構文を示す。
(nl_join
(scan
(scan
(scan
...............
(scan
(scan
)
222
t1)
t2)
t3)
tN-1)
tN)
Adaptive Server Enterprise
付録 A
抽象プランの仕様
上記は、次の構文の省略形である。
(nl_join
(nl_join
.........
(nl_join
(nl_join
(scan t1)
(scan t2)
)
(scan t3)
)
.......
)
(scan tN)
)
•
抽象プランの抽出テーブルを返す。
これは、指定した抽象プランの抽出テーブルをジョインした結果である。
参照
クエリ・プロセッサ
m_join、h_join、join
223
rep_xchg
rep_xchg
説明
xchg オペレータの変形。子抽出テーブルは n の方法で複写される。n は抽象プ
ランの構文で指定される。
構文
( rep_xchg derived_table n)
パラメータ
derived_table
複写される子抽出テーブル。
n
子抽出テーブルが複写される方法の数。これは、複写の並列度とも呼ばれる。
例
テーブル r を 3 つの方法で複写し、3 つの方法で分割されたテーブル s とジョ
インする。この例では、ジョインされる 3 つのストリームの結果をマージ可能
な xchg オペレータも使用する。
select * from r, s where r1 = s1
plan
"
(xchg 1
(nl_join
(rep_xchg 3
(scan r)
)
(scan s)
)
)"
使用法
参照
224
•
戻り値は、複写された抽出テーブルである。
•
このオペレータは並列モードでのみ使用でき、ジョイン・オペレータのみ
に関して使用する。
•
インデックスがジョイン述部のカラムに定義されているが、これはテーブ
ルの分割がジョイン述部に関して役に立たないと思われる場合に、大きな
内部テーブルに対して便利である。このテーブルを再分割すると、イン
デックスを使用する利点がなくなる。この場合、大きい内部テーブルと
パーティション数を同じにするために、外部テーブルを複写するのが便利
である。
•
rep_xchg を任意の位置に配置して、親オペレータが関係演算子を正しく評
価できない場合、クエリ・プロセッサはそれを効果的でないと見なす。
•
コマンド
xchg
Adaptive Server Enterprise
付録 A
抽象プランの仕様
scalar_agg
説明
スカラ集合を実行するのに使用する ScalarAgg オペレータの位置を指定する。
構文
(scalar_agg derived table)
パラメータ
derived_table
derived_table は、集合を実行する子抽出テーブルである。
例
例 1 scalar_agg によって、min と max 最適化を許可するインデックス・スキャ
ンを実行する。
select max(t1) from t where t2=0
plan
“(scalar_agg
(i_scan it1 t)
)”
例 2 テーブル・スキャンとハッシュベースの union オペレータを実行する。
create view av(av1, av2)
as
select max(t1), min(t1) from t
select * from av
union
select s1, s2 from s
plan
“(h_union_distinct
(scalar_agg
(t_scan t)
)
(t_scan s)
)”
例 3 外部テーブル・スキャンを実行し、サブクエリ内で相関カラムのインデッ
クス・スキャンを実行する。
select * from r
where r1 > (select max(s1) from s where s2=t.t2)
plan
“(nested
(t_scan r)
(subq
(scalar_agg
(i_scan is2 s)
)
)
)”
クエリ・プロセッサ
225
scalar_agg
使用法
参照
226
•
戻り値は、1 行に集約された抽出テーブルである。
•
クエリには、スカラ集合 ( たとえば、min、max、count、または avg 集合
関数で、group by 句以外 ) を含める必要がある。
•
scalar_agg 抽象プラン・オペレータは、そのルートまでのプランをカバー
していなくても抽象プランは効果的なため、ルートに集合のないプランに
のみ便利である。
•
scalar_agg 抽象プラン・オペレータは、集合関数を含み、group by のな
い関係式の from 句にあるクエリで集約されたテーブルの完全なセットで
のみ正当である。
•
集合が必要な場合、scalar_agg 抽象プラン・オペレータは必須である。
•
スカラ集合の特別な処理には、事前処理が必要な場合がある。たとえば、
sum/count として avg 計算を設定する、別の処理ステップとして join から
スカラ集合を抽出する、別の集合処理ステップを使用して非相関サブクエ
リのスカラ結果を実体化するなど、これらはすべて事前処理が必要であ
る。これらは、コストベースの演算ではなく、ルールベースの演算である。
•
抽象プランは、事前処理には影響を与えない。これらはクエリ・プロセッ
サをガイドするだけで、クエリ・プロセッサ入力は事前に処理されたクエ
リである。
join、nested、subq
Adaptive Server Enterprise
付録 A
抽象プランの仕様
sequence
説明
1 番目から、最後から 2 番目までの子抽出テーブルの評価を指定する。最後の
抽出テーブルは、これらの評価が終了してから評価される。
構文
(sequence derived_table_1 derived_table_2...derived_table_N)
パラメータ
derived_table
評価されるテーブルの名前。
例
例 1 結合できないスカラ集合で、2 つの処理ステップを必要とする。
select sum(distinct t1), max(t2) from t
plan
*( sequence
( scalar_agg
( i_scan it2 t)
)
( scalar_agg
( distinct_sorted
( i_scan it1 t)
)
)
)”
例 2 最初のステップとしてセルフジョインがワークテーブルに実体化され、2 番
目のステップでワークテーブルは 2 回スキャンされる。
create view dv(dv1, dv2)
as
select distinct t1, t2 from t
select * from dv a, dv b where a.dv1=b.dv2
plan
“( sequence
( store
( distinct_hashing
( t_scan t )
)
)
(m_join
( sort
( t_scan ( work_t (a dv)))
)
( sort
( t_scan ( work_t (b dv)))
)
)
)”
クエリ・プロセッサ
227
sequence
使用法
参照
228
•
戻り値は、最後の子によって返された抽出テーブルである。
•
事前に処理されるクエリには、複数の処理ステップが必要である。
•
sequence 抽象プラン・オペレータを追加することは、完全な抽象プラン
を作成する必要がある場合、または sequence の親オペレータを実行する
場合にのみ便利である。それ以外の場合、各処理ステップに抽象プランの
一部分だけが必要なときは、(hints...) も使用できる。
•
前のバージョンの Adaptive Server では、クエリ・プロセッサはワーク・
テーブル指向で、多くのクエリで複数のステップが使用されていた。
Adaptive Server 15.0 では、いくつかのクエリ実行プラン・オペレータの実
装詳細と処理において 1 つのステップだけを使用しているため、通常ワー
ク・テーブルは隠されている。ユーザは、ほとんどの抽象プランで複数の
ステップを記述する必要はない。しかし、まだ複数のステップが必要な場
合もある。たとえば、スカラ集合には 2 つのステップが必要である。
•
例 2 で示すように、ワーク・テーブルもセルフジョインされた、実体化さ
れたビューで使用される。
scalar_agg、store
Adaptive Server Enterprise
付録 A
抽象プランの仕様
sort
説明
子抽出テーブルをソートする。
構文
( sort derived_table )
パラメータ
derived_table
ソートされる子抽出テーブル。
例
例 1 このプランは、テーブル s と r のマージ・ジョイン順を設定し、子の順序
が正当であることを保証する。外部の子 t_scan は順序付けされず、s2 でソー
トされる。r に対する一番コストの低いアクセス方法がすでに必要な順序付け
を行っている場合、scan r での sort は効果的ではない。
select r1, s1 from r, s where r2=s2
plan
"(m_join
(sort
(t_scan s)
)
(sort
(scan r)
)
)"
例 2 このプランは、r が r1 または r2 にインデックスを持たない場合、t_scan r
をソートすることによってコストの低い merge_union_distinct を可能にする。
s(s1, s2) と t(t1, t2) のインデックスは、このプランを hash_union_distinct
ベースのプランよりも最適にするコストの低い順序付けを提供する。
select r1, r2 from r
union
select s1, s2 from s
union
select t1, t2 from t
plan
"(merge_union_distinct
(sort
(t_scan r)
)
(i_scan is12 s)
(i_scan it12 t)
)"
例 3 ネストループ・ジョインが実行される前に、テーブル r の早期ソートを実
行する。外部テーブル r の順序付けは、order by 句で必要な順序付けを満たす
ジョイン以外で保持される。このプランは、order by 句のソートがジョインの
後に実行される場合、そのジョインが結果カーディナリティを増やすためにコ
ストが高くなる。
select r1, s1 from r, s where r2<s2
order by r1
plan
"(nl_join
クエリ・プロセッサ
229
sort
(sort
(t_scan r)
)
(i_scan is2 s)
)"
使用法
参照
230
•
戻り値は、順序付けされた抽出テーブルである。
•
順序付けは物理プロパティである。なぜなら、それがプランの一部を形成
する実際の物理オペレータに依存し、いくつかの親物理オペレータのアル
ゴリズムによって必要なためである。
•
順 序 付 け は、MergeJoin、MergeUnionDistinct、DistinctSorted、お よ び
GroupSorted など、数多くのコストの低いオペレータを可能にする便利な
物理プロパティである。
•
順序付けは、子オペレータによって提供される場合に使用できる。
•
いくつかのオペレータは、IndScan や sort などの順序付けを生成する。
•
他のオペレータは、それらの子の順序付けを保持する。ネストループ・
ジョインとマージ・ジョインは、それらの外部の子の順序付けを保持する。
•
sort は結果の関係内容を修正しないが、ローの順序付けのみを修正するコ
ストの高いオペレータである。
•
常に、既存の子から取得した順序付けを使用する方がコストが低くなる。
sort は、子が必要な順序付けを提供しない場合に便利である。
•
クエリ・プロセッサは、クエリのセマンティックを基にして、順序付けが
必要な属性を計算する。sort 抽象プラン・オペレータでは、sort キーを指
定する必要はない。クエリ・プロセッサが、必要なすべてのカラムをソー
トする。
•
sort 抽象プラン・オペレータが、必要なすべての順序付けがすでに使用可
能である子に設定されている場合、sort は生成されず、子抽出テーブルが
直接返される。
•
コマンド
enforce、rep_xchg、xchg
Adaptive Server Enterprise
付録 A
抽象プランの仕様
store
説明
子抽出テーブルの評価の結果を格納する。
構文
( store derived_table)
パラメータ
derived_table
実体化される子抽出テーブルの名前。
例
この例は、distinct オペレータを含むビューをセルフジョインする。これは、最
初にビューを実体化し、次にセルフジョインを実行する。ビューは、sequence
オペレータの最初のセクションで評価され、結果が実体化される。ワーク・
テーブルは、sequence の 2 番目のセクション中に、マージ・ジョインを使用
してそのテーブル自身にジョインされる。これらのステップは、同じビューを
2 回評価するよりも効果的である。
create view vg(v1, v2)
as
select distinct t1, s2 from s, t
where s1 = t1 and t3 = 1
select * from vg a, vg b
where a.v1 = b.v1 and a.v2 b.v2
plan
(“sequence
(store
(distinct hashing
(n1_join
(t_scan s)
(scan t)
)
)
)
(m_join
(sort
(t_scan (work_t (b Worktable)))
)
(sort
(t_scan (work_t (a Worktable)))
)
)
)”
使用法
参照
クエリ・プロセッサ
•
store オペレータで指定した抽出テーブルは、ワーク・テーブルでスキャ
ンされ、実体化される。
•
store オペレータで作成されたワーク・テーブルは、Worktab1、Worktab2 など
として参照できる。
store_index、sequence
231
store_index
store_index
説明
StoreIndex オペレータの位置を指定する。これは、一般的な再フォーマット方
式でもある。この方式では、子抽出テーブルが実体化され、クラスタード・イ
ンデックスがジョイン・カラムに構築される。
構文
( store_index derived_table)
パラメータ
derived_table
再フォーマットされる子抽出テーブル。
例
例 1 この抽象プランは、各検索句のスキャン限定インデックスを使用する。ネ
ストループ・ジョイン内では、インデックス・スキャンの結果が、ジョイン・
カラム r1 でインデックスが付けられたワーク・テーブルに再フォーマットさ
れる。
select * from r, s
where
r1=s1
and r2=0
and s2>0
plan
“(n1_join
(i_scan is2 s)
(store_index
(i_scan ir2 r)
)
)”
例 2 この抽象プランは、検索句でスキャン限定インデックスを使用する。ここ
では、インデックス・スキャンの結果が、ジョイン・カラム r1 でインデック
スが付けられたワーク・テーブルに再フォーマットされる。order by が必要と
する順序付けは、r(r3) インデックス・スキャンによって提供され、ネストルー
プ・ジョインによって保持される。
select r3, s3 from r, s
where
r1=s1
and s2=0
order by r3
plan
“(nl_join
(i_scan ir3 r)
(store_index
(i_scan is2 s)
)
)*
232
Adaptive Server Enterprise
付録 A
抽象プランの仕様
例 3 この抽象プランは、ネストループ・ジョイン内により低いマージ・ジョイ
ンとその順序付けを提供するインデックス・スキャンを配置する。これは、
マージ・ジョインの上に store_index を配置することによって、マージ・ジョ
インが繰り返し評価されるのを防ぐ。マージ・ジョインがカラム r(r2) で必要
とする順序付けは、インデックス・スキャンによって提供され、ネストルー
プ・ジョインによって保持される。
select r4, s4, t4 from r, s, t, u
where
r1=s1
and s2=t2
and s3 like “%abcdef%”
and t3 like “%123456%”
and r2=u2
plan
“(m_join
(nl_join
(i_scan ir2 r)
(store_index
(m_join
(i_scan is2 s)
(i_scan it2 t)
)
)
)
(i_scan iu2 u)
)”
使用法
参照
クエリ・プロセッサ
•
戻り値は、再フォーマットされたワーク・テーブルのインデックス・ス
キャンによって生成された抽出テーブルである。
•
前のバージョンの Adaptive Server では、再フォーマットとはワーク・テー
ブルに抽出テーブルを格納し、親ジョインによって使用される属性にクラ
スタード・インデックスを作成することである。これにより、ネストルー
プ・ジョイン内でワーク・テーブルのインデックス・スキャンを配置でき
るようになる。
•
前のバージョンでは、1 つのテーブル・スキャンのみが再フォーマットさ
れていた。Adaptive Server 15.0 では、再フォーマットはどの抽出テーブル
にでも実行される。例 2 に示すように、2 つのテーブル・ジョインの結果
はワーク・テーブルに格納される。
•
store_index は sort が関連するため、コストの高いオペレーションである。
•
Adaptive Server 15.0 では、マージ・ジョインとハッシュは store_index の
必要性を削減する。これは、その内側にあるネストループ・ジョインと
store_index が、マージ・ジョインとソートの双方よりもコストが低い場
合に便利である。しかし、そのような場合、store_index の抽出テーブル
は小さく、外部テーブルが大きくなる。
nl_join、h_join、m_join、sort
233
union
union
説明
union オペレータの 1 つの位置を指定する。
構文
( union derived_table...)
パラメータ
derived_table
union オペレータの両側に使用する抽出テーブル。
例
例 1 このプランは、union の両側でテーブル・スキャンを実行する。
select * from t where t1>0
union
select * from s where s1>0
plan
“(union
(t_scan t)
(t_scan s)
)”
例 2 このプランでは、クエリ・プロセッサは union プランの一部分のオペレー
タを選択し、外側でテーブル・スキャンを実行するハッシュ・ジョイン内で
union を実行する。
create view uv(uv1, uv2)
as
select * from r
union
select * from s
select * from t, uv where t1=uv1
plan
“(h_join
(t_scan t)
(union
(scan r)
(scan s)
)
)”
使用法
234
•
戻り値は、union 抽出テーブルである。
•
クエリのセマンティックでは、union が必要である。
•
union のそれぞれの子抽象プランは、union 側に一致するクエリの一部分
に対応している必要がある。
•
事前処理中、union とジョインは順序が変わる場合がある。これは、コス
トベースの演算ではなく、ルールベースの演算である。
•
抽象プランは、事前処理には影響を与えない。それらはクエリ・プロセッ
サのみをガイドし、クエリ・プロセッサ入力は事前に処理されたクエリで
ある。
Adaptive Server Enterprise
付録 A
参照
クエリ・プロセッサ
抽象プランの仕様
•
クエリ・プロセッサは、これが union all なのか、union distinct なのかを
クエリから認識する。抽象プランは指定する必要はない。
•
各 union all/distinct プランには、いくつかの物理オペレータがある。クエ
リ・プロセッサは、最適なコストベースの物理オペレータを選択する。
h_union_distinct、m_union_distinct、union_all、m_union_all
235
union_all
union_all
説明
union all 演算を実行する AppendUnionAll オペレータの位置を指定する。
構文
( union_all derived_table … )
パラメータ
derived_table
union all オペレータの両側の抽出テーブルを示す。
例
例 1 このプランは、union の両側で union all オペレータとテーブル・スキャン
を実行する。
select * from t where t1>0
union all
select * from s where s1>0
plan
"(union_all
(t_scan t)
(t_scan s)
)"
例 2 このプランでは、クエリ・プロセッサは union_all の子のオペレータを選択
し、外側でテーブル・スキャンを実行するハッシュ・ジョイン内で union を実行
する。
create view uv(uv1, uv2)
as
select * from r
union all
select * from s
select * from t, uv where t1=uv1
plan
"(h_join
(t_scan t)
(union_all
(scan r)
(scan s)
)
)"
使用法
参照
236
•
戻り値は、union 抽出テーブルである。
•
クエリのセマンティックでは、重複を保持する union が必要である。
•
クエリには、union all が含まれている必要がある。
•
union_all は基本の union all オペレータで、それぞれの子を排出する。
•
このオペレータは、union all にのみ正当である。クエリ・プロセッサは、
重複ローを拒否する必要のある union [distinct] ではそれを拒否する。
•
コマンド
union、m_union_all
Adaptive Server Enterprise
付録 A
抽象プランの仕様
update
説明
子抽出テーブルで update 文の位置を指定する。
構文
( update derived_table )
パラメータ
derived_table
更新するローを修飾し、新しい値を提供する子抽出テーブル。
例
ローは、インデックス・スキャンによる更新で修飾される。
update t set t1=t2+1 where t1<0
plan
"( update
( i_scan it1 t )
)"
使用法
参照
クエリ・プロセッサ
•
クエリは、update 文の一部である必要がある。
•
update 抽象プラン・オペレータは、ルートに update Lava オペレータを含
まないプランにのみ便利である。
•
update SQL 文は、役に立つ抽出テーブルを返さない。代わりに、その結果
によって、結果テーブルに変更が行われる。しかし、抽象プラン・オペ
レータのツリーはクエリ実行プラン・オペレータのツリーに一致する必要
があるため、クエリ実行プランで update の親も記述する抽象プランを使
用する必要がある場合は、抽象プラン update オペレータを使用する必要
がある。
•
コマンド
delete、insert
237
use optgoal
use optgoal
説明
クエリに使用される最適化目標のディレクティブを指定する。
構文
( use optgoal optgoal_name )
パラメータ
optgoal_name
クエリに使用される最適化目標の名前。
例
このディレクティブは、クエリの allrows_dss 最適化目標の使用を指定する。
select * from publishers p, titles t
where t.pub_id = p.pub_id
plan
“(use optgoal allrows_dss)”
使用法
参照
238
•
最適化目標は、指定されたクエリのみに適用される。
•
クエリ・レベルの指定は、最適化目標のセッション・レベルまたはサー
バ・レベルの指定を上書きする。
•
デフォルトの最適化目標は、allrows_mix である。allrows_dss は、実験的
に使用可能である。
•
その他の抽象プラン・オペレータは、use optgoal ディレクティブを使用
して指定することはできない。
use opttimeoutlimit
Adaptive Server Enterprise
付録 A
抽象プランの仕様
use opttimeoutlimit
説明
クエリに使用される最適化のタイムアウト制限のディレクティブを指定する。
最適化タイムアウトは、Adaptive Server がクエリの最適化に必要な予想クエリ
実行時間の割合を示す。
構文
(use optgoal opttimeoutlimit_value)
パラメータ
opttimeoutlimit_value
タイムアウト制限の値。
例
この例は、クエリに 100% の最適化タイムアウト制限を使用するディレクティ
ブを示す。
select * from publishers p, titles t
where t.pub_id = p.pub_id
plan
“(use opttimeoutlimit 100)”
使用法
参照
クエリ・プロセッサ
•
最適化タイムアウト制限は、指定されたクエリのみに適用される。
•
クエリ・レベルの指定は、最適化タイムアウト制限のセッション・レベル
またはサーバ・レベルの指定を上書きする。
•
opttimeoutlimit の有効な値は 0 ~ 1000。デフォルト値は 10。
•
その他の抽象プラン・オペレータは、use opttimeoutlimit ディレクティブ
を使用して指定することはできない。
use optgoal
239
values
values
説明
テーブルのリテラルの位置を指定する。
構文
( values )
例
このプランは、テーブル・スキャンと 2 つのテーブル・リテラルで union を実
行する。
select t1 from t
union
select 1
union select 2
plan
"(h_union_distinct
(t_scan t)
(values)
(values)
)"
使用法
参照
240
•
戻り値は、抽出テーブルとしてのテーブル・リテラルである。
•
テーブル・リテラルは、テーブル値のコンストラクタ、from 句のない select
関係式、または insert 文の values 句によって SQL で提供される。
•
values 抽象プラン・オペレータは、より大きな抽象プランが必要な場合に
のみ便利である。
•
クエリにいくつかのテーブル値コンストラクタが含まれている場合、
values 抽象プラン・オペレータはそれらと位置的に一致する。
•
コマンド
insert、scalar_aggh_join
Adaptive Server Enterprise
付録 A
抽象プランの仕様
xchg
説明
xchg (「exchange」と発音する ) は、並列クエリ・プランを構築するための
キー・オペレータである。xchg は、子抽出テーブルに指定した「並列度」で
テーブルの再分割を実行する。並列度の値は、作成されるパーティションの数
である。再分割は動的なオペレーションで、再分割の結果は実体化されない。
構文
( xchg derived_table n)
パラメータ
derived_table
再分割を適用する子抽出テーブル。
n
子抽出テーブルの再分割の数。
例
例 1 この項の例ではこのテーブルを使用する。
create table r(r1 int, r2 int, r3 int)
partition by range(r1, r2)
(
p1 values <= (100,100),
p2 values <= (200,200),
p3 values <= (300,300)
)
create table s(s1 int, s2 int, s3 int)
partition by hash (s2)
(p1,p2,p3,p4)
この並列スキャン ( 並列処理を有効に設定 ) では、xchg はテーブル r のスキャ
ンから抽出した 3 つのストリームを取得し、
「多対一」の xchg オペレータを使
用して、それらのストリームを 1 つにマージする。
select * from r
plan
"(xchg 1
(scan r)
)"
例 2 2 つの分割されたテーブルを並列にジョインする。テーブル r のパーティ
ションはジョイン述語には役に立たず、テーブル s と同じスキームで再分割さ
れる必要がある。再分割するカラム、分割のタイプ、またはパーティションの
限界値を指定する必要はなく、再分割の並列度だけを指定する。
select * from r, s
where r2 = s2
plan
"(xchg 1
(join
(xchg 4
(scan r)
)
クエリ・プロセッサ
241
xchg
( scan s)
)
)"
この例では、最初の xchg オペレータ (xchg 1) は、多対一モードを使用し、入
力ストリームをマージして、1 つのストリームに形成する。クエリ・プロセッ
サは次の xchg オペレータ (xchg 4) を使用して、多対多の再分割を実行する。
この場合、範囲分割されたベース・テーブルは、ハッシュ分割を使用して 4 つ
の方法に再分割され、次にテーブル s にジョインされる。
例 3 この例では、テーブル r にグループ化集合が含まれている。xchg 2 オペ
レータは、スキャンの出力によって作成された抽出テーブルを再分割する。この
再分割はグループ化カラムで実行され、group-hashing オペレータは並列にグルー
プ化を実行する。このグループ化の結果は 2 つのストリームを作成し、これらの
ストリームは QEP の上部で xchg 1 オペレータを使用してマージされる。
select count(*), r1 from r group by r1
"plan
"(xchg 1
(group_hashing
(xchg 2
(t_scan r)
)
)
)"
使用法
参照
242
•
子抽出テーブルに適用された xchg の結果は、再分割されたストリームで
ある。
•
1 の xchg 値は、クエリ・プロセッサにデータ・ストリームをマージする
よう通知する。
•
1 より大きい xchg 値は、
「多対多」または「一対多」オペレータのいずれ
かで、子抽出テーブルの分割による。
•
子抽出テーブルにすでに分割されたプロパティがあるために、クエリで
xchg オペレータが必要ない場合、クエリ・プロセッサは xchg オペレータ
を適用しない。
•
クエリ・プロセッサは、適切な分割とこの分割が必要なカラムを評価する。
rep_xchg、enforce
Adaptive Server Enterprise
用語解説
CPU コスト (CPU cost)
オプティマイザがクエリを処理するために必要な CPU の概算値。
histogram tuning factor
頻度セルが存在する場合にのみ、デフォルトのステップ数または指定され
たステップ数を超えるステップ数をヒストグラムで設定するために使用
するチューニング係数。たとえば、ディストリビューションに頻度セルが
存在し、この係数が 3 の場合、ステップ数をデフォルトの 20 から 60 に増
やすことができます。
lava オペレータ
(lava operator)
基本の演算の 1 つを実装し、オプティマイザによって lava クエリ・プラ
ンの一部として選択可能な独立したソフトウェア・オブジェクト。次に、
lava オペレータの例を示します。たとえば、データベース・テーブルから
ローを読み取る ScanOp、マージ・ジョインを実装する MergeJoinOp、
テーブルにローを挿入する InsertOp などです。lava オペレータは 32 種類
あります。
lava クエリ・プラン
(lava query plan)
複数の lava オペレータからなる逆ツリー構造。最上位のオペレータが 1 つ
または複数の子オペレータを持ち、子オペレータがさらに 1 つまたは複数
の子オペレータを持つというようにして、オペレータの逆ツリー構造が構
成されます。オプティマイザが lava クエリ・プランの正確なツリーの形
とオペレータを選択し、lava クエリ実行エンジンがプランを実行します。
lava クエリ実行エンジン
(lava query execution
engine)
オプティマイザによって選択された lava クエリ・プランを実行する
Adaptive Server のモジュール。クエリ・プランは、プラン内の最上位のオ
ペレータ (RootOp) のメソッドを呼び出すことによって実行されます。最
上位のオペレータは子オペレータのメソッドを呼び出し、子オペレータが
さらにその子オペレータのメソッドを呼び出すというようにしてリーフ・
オペレータまでのメソッドが呼び出され、必要に応じて結果ローが生成さ
れます。結果ローはリーフ・オペレータ・ノードで生成され、オペレー
タ・ツリーを経由して最上位の RootOp に返されます。RootOp は、結果
ローをコンシューム ( クライアントに送信したり、変数に値を割り当てる
など ) します。
LIO
OLTP
PIO
クエリ・プロセッサ
「論理 I/O コスト (logical I/O cost)」参照。
オンライン・トランザクション処理のことで、最小限のリソースを使用す
るクエリを含む、短時間のトランザクションを多数処理することを特徴と
するアプリケーション。
「物理 I/O コスト (physical I/O cost)」参照。
243
用語解説
UTF-16
16 ビット形式の UCS ( 国際標準の汎用文字セット ) 変形フォーマット。
UTF-16 で
は、各 UCS-2 コード値はそれ自体を表します。BMP (Basic Multilingual Plane:
0..0xFFFF) の範囲外のコード値は、サロゲート・ペアという特別な 16 ビットの
コードを使用して表現します。これにより、220 バイト (1MB) のコード値を追加
で表現できますが、そのためには 4 バイトを使用する必要があります。
UTF-8
8 ビット形式の UCS 変形フォーマット。UTF-8 は Unicode 標準の可変長コード
化形式で、8 ビット・シーケンスを使用します。上位ビットは、バイトがシー
ケンスのどの部分に属するかを示します。
意思決定支援システム
(DSS: Decision
Support System)
大量のデータを処理するクエリの実行を特徴とするアプリケーション。
インオーダ・ジョイン
(in-order join)
外部ジョインのジョイン属性の一部 ( または全部 ) が、ソートまたはインデッ
クス・スキャンを実行した場合のように順番に並んでいるジョイン操作。
インデックス交差
(index intersection)
1 つのテーブルにある 2 つ以上のインデックスで取得した複数の RID を結合
するアクセス・パス。and で結合された複数の探索引数を使用するテーブル・
スキャンの結果セットの条件を満たす RID のセットを取得します。
インデックス和集合
(index union)
1 つのテーブルにある 2 つ以上のインデックスで取得した複数の RID を結合
し、重複を削除するアクセス・パス。or で結合された複数の探索引数を使用
するテーブル・スキャンの結果セットの条件を満たす RID のセットを取得し
ます。
枝分かれの多いツリー・
プラン (bushy tree
plan)
いくつかのジョイン演算を含み、そのジョイン演算がさらにジョイン演算であ
る 2 つ以上の直接の子を持っているクエリ・プラン。通常、枝分かれの多くな
いプランは左側の深いツリーと呼ばれます。左側の深いツリーの右側の子は
scan オペレータ ( ジョイン・リスト ) で、ジョイン・リスト内のテーブルはリ
ニア順でジョインされます。
枝分かれの多い並列処理
(bushy parallelism)
複数の CPU が複雑なクエリ・プランの異なるサブプランを並列に実行すると
きに発生します。
格納処理
(store operator)
完全に実体化されたテーブルを作成する処理。通常は、再フォーマット方式の
サポートに使用します。
仮想カラム
(virtual column)
実行エンジンの処理の出力に表示される、テーブルの永続的なカラムに直接
マップされないカラム。ほとんどの場合 ( 常にとは限らない )、式は join の一
方の側に関連します。
キャッシュ方式
(cache strategy)
実行エンジンがクエリで参照される明示的なテーブルのページを処理するた
めに使用するバッファ・キャッシュの特性や、クエリの内部処理に使用される
一時的な情報についての、オプティマイザの指定。
グローバル・インデック
ス (global index)
分割されたテーブルのインデックス。グローバル・インデックスは、インデック
スとテーブルの分割方式が異なる場合に作成され、グローバル・インデックスの
インデックス・リーフ・ページが複数のパーティションを指すようにします。
244
Adaptive Server Enterprise
用語解説
グローバル統計
(global statistics)
テーブルのすべてのデータ値に適用される統計。
検索エンジン
(search engine)
クエリ・オプティマイザのコンポーネントの 1 つ。代替実行プランを生成して
評価し、最適なプランを選択します。検索エンジンは、検索基準、検索領域、
検索方式という 3 つのキー・コンポーネントで構成されます。
検索基準
(search criteria)
プランの生成に使用する最適化テクニックを決定するために使用される、ユー
ザ指定またはシステム定義の基準。
検索方式 (search
strategy)
検索エンジンのモジュールの 1 つ。特定の検索領域を生成し、その検索領域内
に含まれる代替プランの中からプランを選択します。
検索領域 (search space)
検索エンジンがプランを選択するときに考慮するプランの包括的なセット。
交換処理 (exchange
operator)
データ・ストリームに適用して、ストリームの並列度やデータ・セマンティッ
クを変更できる処理。再分割に利用されます。交換処理には、プロデューサ・
サイドとコンシューマ・サイドがあります。プロデューサ・タスクでは、交換
処理の下で関係演算子の複製が実行されます。コンシューマ・サイドでは、コ
ンシューマ処理に必要なのと同じ数の複製で実行されます。
コード生成 (code
generation)
オプティマイザが使用するプランの表示は、競合する最適なプランの効率的な
比較のために設計されていますが、実行エンジンが使用するプランの表示は、
効率的な実行のために設計されています。コード生成とは、オプティマイザの
最適なプランの表示を実行エンジンのプランの表示に変換する、クエリのコン
パイルのメカニズムです。
コストベースの排除
(cost based pruning)
コストの高い他のサブプラン分析方法の代わりにサブプランの見積もりコス
トを使用する、クエリの最適化テクニック。
混合負荷 (mixed
workload)
リレーショナル・クエリには、大きく分けて、OLTP 環境で実行される単純な
トランザクション・クエリと、DSS 環境で実行される複雑なクエリとがありま
す。運用環境では、トランザクション・クエリまたは複雑なクエリを、同時ま
たは時間をずらして実行するように、データベース・システムを設定します。
これらの両方のクエリをサポートするシステムを「混合負荷」システムと呼び
ます。負荷の種類を常に予測できるとは限らないため、すべての種類の負荷を
効率的にサポートできるように、OLTP クエリと DSS クエリの両方を同じ設定
のデータ処理システムでサポートすることが重要です。
コンパイル
(compilation)
クエリ・テキストを分析して、実行エンジンに提供するクエリ・プランを作成
するクエリ処理の段階。
最適化タイムアウト
(optimization timeout)
コンパイル時間が指定した基準を超えたときに、オプティマイザが現在の最適
プランよりも優れたプランの検索を終了するメカニズム。その場合、現在の最
適なプランがクエリの処理に使用されます。
最適化目標
(optimization goal)
最適化テクニックを選択するときに考慮される、一連のユーザ定義の目標。こ
の目標を指定することにより、特定のクエリまたはアプリケーションに適した
プランを生成できます。
クエリ・プロセッサ
245
用語解説
最適化ルール
(optimization rules)
最適なプランを決定する場合、オプティマイザによって行われる決定のほとん
どは見積もりコストを基にしています。いくつかの決定は、クエリ述部やクエ
リに関連するテーブルの特定の特徴を基に行われます。たとえば、スター・
ジョインの場合を除いて、2 つのテーブル間にジョイン述部を持つのが最適で
す。これは、他のジョイン順の順列が評価されないためです。
サロゲート・ペア
(surrogate pairs)
2 つのコード値のシーケンスから成る 1 つの抽象文字の、コード化された文字
表現。サロゲート・ペアは、220 バイトのコード値を Unicode 標準に追加でき
るように設計されています。この概念は、UTF-16 エンコーディングだけに適
用されます。
算術演算子
(arithmetic operator)
SQL 文で 算術式を作成できるようにするための記号。加算 (+)、減算 (-)、除算
(/)、乗算 (*) は、数値カラムに使用できます。モジュロ (%) は、integer データ型
でのみ使用可能です。
「比較演算子 (comparison operator)」参照。
射影 (projection)
オペレータの出力で使用できる属性のセット。属性の最小限のセットで、この
セットに含まれる各属性は、各オペレータの親に必要です。
順序 (ordering)
インデックス・スキャンやソートによって返される結果セットに含まれる属性
の特定の順序 ( 昇順または降順 )。
ジョイン密度
(join density)
「総密度 (total density)」参照。
ジョイン・ヒストグラム
(join histogram)
最適化の実行中にだけ作成され、その後廃棄される中間ヒストグラム。等価
ジョインされた 2 つのカラムのヒストグラムを取得し、ジョイン発生後のデー
タの分散をモデル化するヒストグラムを生成することによって作成されます。
推移閉包
(transitive closure)
等価ジョインで接続された属性のセット。
垂直並列処理
(vertical parallelism)
プランの 1 つのフラグメント内の複数の処理に対して、複数の CPU を同時に
使用する機能。パイプライン並列処理とも呼ばれます。
水平並列処理
(horizontal parallelism)
分割並列処理と独立並列処理は、水平並列処理に分類されます。異なる記憶単
位に配置された異なるデータ・セットで複数インスタンスの処理を実行する機
能も、水平並列処理または分割並列処理と呼ばれます。
スカラ (scaler)
値のセットではなく、1 つの値を生成する SQL 式の用語。
スター・スキーマ・
ジョイン (star
schema joins)
複数のディメンション・テーブルが中央ファクト・テーブルにジョインされて
いるクエリ。ディメンション・テーブル間 ( 外積 ) に join 句はなく、ファクト・
テーブルはそれにジョインされているディメンション・テーブルよりも大規模
です。
スノーフレーク・ス
キーマ・ジョイン
(snowflake
schema joins)
複数のディメンション・テーブルがローカルなファクト・テーブルにジョイン
され、それらのファクト・テーブルが 1 つの中央ファクト・テーブルにジョイ
ンされているクエリ。ディメンション・テーブル間 ( 外積 ) に join 句はありま
せん。ファクト・テーブルは、それにジョインされている各ディメンション・
テーブルよりも大規模です。
246
Adaptive Server Enterprise
用語解説
セミジョイン (semijoin)
ジョイン・アルゴリズムの 1 つ。基準を満たす最初の内部ローが見つかった時
点で各外部ローの内部スキャンを終了します。
存在スキャン
(existence scan)
スキャン・アルゴリズムの 1 つ。完全に基準を満たす最初のローが見つかった
時点でテーブルのスキャンを終了します。通常、フラット化された exists サブ
クエリで参照されるテーブルに使用されます。
タプルのフィルタ
(tuple filtering)
入力ストリームが 1 つの実行処理。参照される属性がすべて順番に並んでいる
ことを前提とし、その前提に基づいて、重複するタプルを削除します。
多方向ジョイン
(multi-way joins)
いくつかのテーブルを含み、それらが 2 つ以上のテーブルにジョインされてス
ター・ジョイン構成やスノーフレーク・ジョイン構成を形成しているジョイ
ン・クエリ。
抽出統計 (derived
statistics)
検索領域の操作中に計算され、使用される統計。クエリ最適化の間は存続しま
す。抽出統計には、すべての述部 ( フィルタリングなど ) が適用された後に存
在する、変更されたヒストグラム、密度、カラム幅、テーブル統計が含まれます。
抽象プラン
(abstract plan)
アクセス・パス上の、Adaptive Server Enterprise のクエリ処理に対する命令。ク
エリを実行するためのデータ ( ジョイン順、ジョイン・アルゴリズム、イン
デックスの使用状況の指定など ) の操作に使用します。
ディメンション・テーブ
ル (dimension table)
スター・スキーマ内でプライマリ・キーの役割を果たすテーブル。同じスター・
スキーマ内の他のディメンション・テーブルと結合して複合キーを作成し、中
央ファクト・テーブルの情報にアクセスしたり、中央ファクト・テーブルの各
情報をジョインしたりできます。
データ・フロー・エンジ
ン (data flow engine)
少ない実体化ステップで大規模なプランを処理する実行エンジンを指す用語。
テーブル正規化ヒストグ
ラム (table normalized
histogram)
update statistics によって計算されるヒストグラム。通常はヒストグラムと呼
ばれます。このヒストグラムのウェイト配列値 ( テーブル・ローの割合 ) の合
計は常に 1.0 となります。
等価パーティション
(equi-partitioned)
互換性のある分割キーと分割基準を持つ 2 つのテーブル。2 つのテーブルが互
換性のあるデータ型の分割キーを同じ数だけ持ち、分割基準 ( 範囲パーティ
ションのインターバルなど ) が同じである場合、2 つのテーブルは等価パー
ティションであると見なされます。
動的パーティション削除
(dynamic partition
elimination)
バインドされていない述部の値が実行時に認識される場合、スキャンするパー
ティションのリストから、1 つ以上のパーティションを消去できます。これは、
値がネストループ・ジョインの内部スキャンで認識されるカラムについても同
じです。
独立並列処理
(independent
parallelism)
枝分かれの多い並列処理とも呼ばれます。「枝分かれの多い並列処理 (bushy
parallelism)」参照。
貪欲な検索方式 (greedy
search strategy)
クエリ・プランを高速に取得するためにオプティマイザが使用する順列方式。
すべてのクエリ・プランを検索するのではなく、非常に粗い基準を使用するた
め、結果は必ずしも最適なプランではありません。
クエリ・プロセッサ
247
用語解説
パーティション排除
(partition elimination)
分割キーに述部を持つクエリを提供して、指定された述部の条件を満たすパー
ティションを調べることができます。ただし、現在パーティション削除に使用
できる述部は、column <relop> <literal> のフォーマットの 1 つのテーブル上
で、結合述部または非結合述部として修飾する必要があります。
排除 (pruning)
オプティマイザが最適な実行プランを検索するテクニック。最適な全体プラン
の一部にできるサブプランだけを保持します。オプティマイザは、コストベー
スの排除とヒューリスティックベースの排除を使用します。
パイプライン処理
(pipelining)
2 組のスレッドが、それぞれプロデューサとコンシューマとして動作する処
理。プロデューサはデータを共有バッファに格納し、コンシューマは共有バッ
ファ内のデータを同時に処理できます。
パイプライン並列処理
(pipelined parallelism)
複数のステップから成る SQL オペレーションにおいて、独立した各ステップ
が、その前のステップの完了前に実行を開始できる処理方式。1 つのクエリを
複数のプロセッサで処理できるため、応答時間を短縮できます。
ハッシュベースの集約
(hash based
aggregation)
group by 集合を評価する方式の 1 つ。グループ化カラムのハッシュ・キーに
よってグループを検索します。
バッファ置換方式
(buffer replacement
strategy)
「バッファ再利用方式 (buffer reuse strategy)」参照。
パラレライザ
(parallelizer)
オプティマイザのコンポーネントの 1 つ。プランにスケジューリング情報を追
加し、プランを再評価し、最適な並列プランを生成します。並列オプティマイ
ザは、リソース使用状況の注釈が付けられている一連の並列プランを検討する
スケジューラおよびパラレライザです。クエリに使用できるリソースの合計に
基づいて、応答時間に応じた最適なプランを決定します。
範囲分割 (range
partitioning)
このテーブル分割スキーマにおいて、1 つまたは複数の属性のデータ・セット
を、値の範囲に基づいて分割します。したがって、各ローを特定のパーティ
ションに確実に格納できます。
反復子 (iterator)
実行エンジンの処理の 1 つ。クエリ結果は、反復子を使用してカプセル化され
ます。この反復子は、null または n-ary データ・セットからのローのストリー
ムを許可する独立したソフトウェア・オブジェクトです。反復子の役割は、多
数のノードにまたがる多数のデータ・セットの反復を逐次または並列で処理す
ることです。反復子が外部反復子 ( 別の反復子 ) である場合、反復子はデータ・
ストリームのソースを認識できません。内部反復子 ( 反復子自体が生成した反
復子 ) である場合は、ソースを認識できます。反復子は、データ・セットが反
復されるたびに、その反復子の指定に従ってデータを操作し、事前に定義され
た動作を処理対象のデータ・セットに適用します。たとえば、ディスク上の
テーブルからローをスキャンする動作は、反復子による動作の一種です。反復
子の重要な機能は、反復子の種類とそれに関連付けられている動作には関係な
く、すべての反復子が同じ手順に従い、同じ外部インタフェースを持つという
点です。すべての反復子は、データ・ストリームを開き、ストリームを繰り返
し読み取り、ストリームを処理し、ストリームを閉じます。
248
Adaptive Server Enterprise
用語解説
汎用カラム
(generic column)
通常はクエリで参照されるテーブルのカラムを指しますが、式のジョインに使
用できる式などを抽象的に指す場合もあります。
汎用テーブル
(generic table)
クエリで参照されるテーブルを指しますが、オプティマイザがジョイン順に配
置するオブジェクトを抽象的に指す場合もあります。たとえば、サブクエリは
汎用テーブルの一例です。
ヒストグラム・ウェイト
配列 (histogram weight
array)
ヒストグラムに関する float 値の配列。セルで選択されたテーブルの割合 ( テー
ブル正規化ヒストグラムの場合 ) か、特定の述部で選択されたセルの割合 ( セ
ル正規化ヒストグラムの場合 ) のいずれかを表します。
左側の深いツリー・プラ
ン (left deep tree plan)
テーブルのセットのジョイン順をツリーベースで言い換えた語。右側のノードが
常にリーフ・ノードである、ツリー状のクエリ・プラン構造を指します。このツ
リー内でのテーブルの順序は、set forceplan オプションの影響を受けます。
ヒューリスティックベー
スの排除 (heuristic
based pruning)
クエリに適用可能な事前に決定された一連の規則に基づいて、検索領域の一部
( 特定のツリーの形や順列など ) を省略する最適化テクニック。
ファクト・テーブル
(fact table)
スター・データベース・スキーマのメイン・テーブル。複数のディメンショ
ン・テーブルの外部キーである属性で構成される、複合キーを持ちます。
フェッチ (fetch)
フェッチは、1 つ以上のローを取得し、現在のカーソル位置をカーソル結果
セットに移動します。カーソル・フェッチとも呼びます。
物理 I/O コスト
(physical I/O cost)
オプティマイザが実行する物理読み込みの回数の見積もり。
物理オペレータ
(physical operator)
インデックス・スキャン、ソートマージ・ジョイン、ネストループ・ジョイン
などの論理演算子を実装するアルゴリズム。
物理プロパティ
(physical property)
物理オペレータに関連付けられたプロパティ。そのオペレータで実装されてい
る実際のアルゴリズムと、その子の物理プロパティに依存します ( したがって、
再帰的に、サブプラン内の物理オペレータに依存します )。たとえば、通常は、
インデックス・スキャンやソートによって返される外部の子の順序が、後続の
ジョイン・オペレータの評価後に継承されます。しかし、サブプランで使用さ
れている基本となるオペレータによっては、同等クラス内の各プランが異なる
順序を持つ可能性もあります。
プラン・キャッシュ
(plan cache)
オプティマイザが、後で完全なプランを作成するときに役立つ可能性がある部
分プラン ( プランのフラグメント ) をプロシージャ・キャッシュに格納するこ
と。プラン・キャッシュはクエリのコンパイル中にだけ存在し、クエリの実行
前に解放されます。
分割キー
(Partitioning key)
パーティション仕様を評価する検索条件。この重要な仕様の指定に関与する一
連のカラムを分割キーと呼びます。
分割並列処理
(partitioned
parallelism)
データを複数の物理パーティションに分割して、各パーティションに並列でア
クセスし、作業スレッドで各パーティションを管理できるようにします。この
ような構成の IO 並列処理と CPU 並列処理では、パーティションの数に比例し
て SQL クエリの処理を高速化できます。
クエリ・プロセッサ
249
用語解説
ラウンドロビン分割
(round-robin
partitioning)
負荷分散に最適な分割方式。データ値をどの位置で分けるかは考慮せず、ラウ
ンドロビン方式でデータ・セットを分散します。
ローカル統計
(local statistics)
分割されたテーブルの特定のパーティションのデータ値に適用される統計。
ローカル・インデックス
(local indexes)
テーブルのインデックスが、テーブルのデータと同じ方法で分割されます。
ローカル・サーバ
(local server)
クエリの発生元のサーバまたはノード。
論理 I/O コスト
(logical I/O cost)
オプティマイザが実行する論理読み込みの回数の見積もり。
論理演算子
(logical operator)
where または on 句のコンテキストにおいて、キーワード and、or、not はロー
をフィルタする述部の一部です。
最適化における論理演算子は、クエリ処理の特定のアルゴリズムを指定しない
オペレーション ( ジョイン、スキャン、ソート ) です。
論理プロパティ
(logical property)
一連のテーブル ( 同等クラス ) と関連付けられた一連のサブプランに共通する
プロパティ。row count はその一例です。これは、テーブルのセットのジョイ
ン方法に関係なく、同じ述部の適用後は同じローが存在するためです。
論理分割 (logical
partitioning)
関数 f がタプル t のキーに適用される場合において、データが n 単位に分割さ
れる方法。論理分割は、唯一のパーティションにマップされる序数を生成しま
す。つまり、0 <= f(t,n) <= n - 1 です。この例外は、このようなマッピングを実
行しないラウンドロビン分割です。
250
Adaptive Server Enterprise
索引
E
記号
() ( カッコ )
SQL 文内
, ( カンマ )
SQL 文内
::= (BNF 表記 )
SQL 文内
[ ] ( 角カッコ )
SQL 文内
{} ( 中カッコ )
SQL 文内
emit
オペレータ 97
exchange
オペレータ 144
exchange
オペレータ 38
パイプ管理 39
ワーカー・プロセス・モデル
xii
xii
xii
xii
40
xii
F
from table 99
function
datachange、統計値
数字
2 フェーズ・スカラ集合
54
B
177
G
Backus Naur Form (BNF) 表記
BNF 表記、SQL 文内 xi, xii
xi, xii
Group Sorted
オペレータ 124
Group Sorted Aggregate
オペレータ 127
C
compute by 処理
130
D
datachange 関数
統計値 177
delete 107
delete 81
delete statistic 190
delete statistics コマンド
統計値の管理 190
drop index コマンド
統計 190
クエリ・プロセッサ
H
Hash Distinct
オペレータ 126
hash join
オペレータ 118
hash union
オペレータ 131
hash vector aggregate
オペレータ 129
251
索引
I
insert
insert
P
process_limit_action
107
81
86
Q
J
QP 測定基準 「クエリ処理測定基準」参照
Job Scheduler
update statistics
179
R
L
Lava
オペレータ 22
クエリ実行 25
クエリ・プラン 21
lava
オペレータ 97
クエリ・プラン 94
Lava クエリ・エンジン 21
log スキャン 105
M
max repartition degree
設定 31
max resource granularity
設定 30
merge join
オペレータ 116
merge union
オペレータ 132
N
nary nested loop join
オペレータ 120
nested loop join 114
O
or list 98
or 述部
ジョイン
252
14
remote scan
オペレータ 141
restrict
オペレータ 135
rid join
オペレータ 143
rid スキャン 103
S
scalar aggregate
オペレータ 134
scan
オペレータ 98
scroll
オペレータ 141
select into
クエリ 78
sequencer
オペレータ 139
set
XML コマンド 148
set
例 33
set rowcount オプション 35
showplan
ASE 15.0 でのクエリ・プラン
使用 86, 89
文レベル出力 91
sort
オペレータ 135
Sort Distinct
オペレータ 125
sqfilter
オペレータ 143
90
Adaptive Server Enterprise
索引
SQL
並列処理 43
SQL テーブル
抽出 19
statistics 句、create index コマンド
statisticsmaintenance 183
statisticssorts、非先行カラム 188
store
オペレータ 137
sysquerymetrics ビュー
クエリ処理測定基準 157
X
XML
set 148
診断出力 148
パーミッション 153
廃止になったトレース・コマンド
183
153
あ
アクセス
クエリ処理測定基準
156
T
text delete
オペレータ 108
truncate table コマンド
カラムレベルの統計値
い
インデックス
update index statistics 185
update statistics 185
探索引数 11
インデックス未設定カラム 173
インデックス・スキャン 48
クラスタード、分割されたテーブルの 52
クラスタード・インデックス 52
グローバル・ノンクラスタード 48
ノンカバード、グローバル・ノンクラスタード 48
ノンクラスタード、分割されたテーブル 52
ノンクラスタード・グローバル・インデックスを
使用するカバード・スキャン 51
183
U
union all
オペレータ 133
逐次 57
並列 56
update 107
update 81
update all statistics 184
update all statistics コマンド 186
update index statistics 184, 185, 188
update statistics 174
update statistics コマンド
with consumers 句 188
カラムレベル 185
カラムレベルの統計値 185
統計値の管理 183
え
演算子
不等号 12
エンジン
クエリ実行
W
with statistics 句、create index コマンド
クエリ・プロセッサ
20
お
183
大文字と小文字の区別
SQL xiii
オブジェクトのサイズ
チューニング 19
オプション
set rowcount 35
253
索引
オプティマイザ
クエリ 3
オペレーション
insert、delete、update 81
オペレータ
delete 107
emit 97
exchange 144
exchange 38
Group Sorted 124
Group Sorted Aggregate 127
Hash Distinct 126
hash join 118
hash union 131
hash vector aggregate 129
insert 107
Lava 22
lava 97
merge join 116
merge union 132
nary nested loop join 120
remote scan 141
restrict 135
rid join 143
scalar aggregate 134
scan 98
scroll 141
sequencer 139
sort 135
Sort Distinct 125
sqfilter 143
store 137
text delete 108
union all 133
update 107
最適化 4
抽象プラン 162
ベクトル集合 127
か
概要
クエリ処理 1
クエリ処理測定基準
角カッコ [ ]
SQL 文内 xii
カッコ ()
SQL 文内 xii
254
155
カラムレベル
統計値 183
カラムレベルの統計値
truncate table 183
update statistics 183
update statistics で生成
カンマ (,)
SQL 文内 xii
185
き
記号
SQL 文内
xi, xii
く
クエリ
IN リストを持つ 71
Lava、実行 25
OR 句 72
order by 句を持つ 74
select into 句 78
オプティマイザ 3
最適化の実行時間の制限 16
最適化の問題 18
実行エンジン 20
実行の設定 89
プラン 90
並列実行モデル 38
並列処理 28
並列で実行されない 85
ローカル変数の設定 35
クエリ処理
概要 1
並列 27
クエリ処理測定基準
sysquerymetrics ビュー 157
アクセス 156
概要 155
クリア 160
実行 156
使用 156
クエリの最適化 147
クエリの並列処理の制御 34
クエリ分析
showplan 89
Adaptive Server Enterprise
索引
クエリ・プラン
Lava 21
lava 94
並列 36
クリア
クエリ処理測定基準 160
グループ化集合関数メッセージ
127
け
結果
並列クエリの結果の変化
34
削減
impact 189
作成
カラムの統計 184
探索引数 18
サブクエリ 75
参照整合性制約 110
サンプリング
統計値 175
統計値更新のための使用
175
し
式
こ
更新
統計値 173, 175, 184
構文
抽象プラン 162
構文規則、Transact-SQL xi
構文上の修飾
抽象プラン 168
構文、新規
抽象プラン 165
さ
最適化
オペレータ 4
クエリ最適化の実行時間の制限
クエリの変形 7
最適化、抽象プラン 165
述部変形 10
探索引数の例 12
追加のパス 10
分析する要素 6
方法 4
目標 15
目標、例外 16
問題 18
最適化目標
抽象プラン 165
再フォーマット
並列処理 64
クエリ・プロセッサ
16
ジョイン 14
実行
set noexec on による防止 89
クエリ処理測定基準 156
実行時
調整 85
調整の管理 86
調整の削減 87
調整の識別 86
実行時調整
実行時 85
自動的な更新
統計値 176
自動的に
update statistics 179
述部
変形 10
出力
XML 診断 148
文 91
順序
ジョイン 14
ジョイン 13
or 述部 14
外部 67
式 14
順序 14
セミ 67
逐次 66
データ型の混在 14
ヒストグラム 13
並列処理 58
255
索引
並列処理、一方のテーブルの分割が有用 59
並列処理、複写 63
並列処理、両テーブルの分割方式が同一で有用
密度 13
両テーブルの分割が有用でない 61
ジョイン・オペレータ 114
使用
showplan 86
クエリ処理測定基準 156
そ
58
ソート
統計値、インデックス未設定カラム
ソート条件
統計値 187
属性の影響を受けない演算
並列処理 44
属性の影響を受ける演算
並列処理 58
測定基準
抽象プラン 167
188
す
推移閉包
探索引数 8
等価ジョイン 8
スカラ集合
2 フェーズ 54
逐次 55
スキャン
インデックス 48
クラスタード・インデックス 52
グローバル・ノンクラスタード・インデックス 48
グローバル・ノンクラスタード・インデックスの
ノンカバード・スキャン 48
ノンクラスタード、分割されたテーブル 52
ノンクラスタード・グローバル・インデックスを
使用するカバード・スキャン 51
分割されたテーブルの
クラスタード・インデックス 52
ローカル・インデックス 52
スキャン・タイプ
統計値 187
スキュー
パーティション 83
せ
セッション・レベルでの並列処理の制御
設定
max scan parallel degree 31
number of worker processes 29
ローカル変数 35
設定、max parallel degree 30
設定、max repartition degree 31
設定、max resource granularity 30
256
32
た
タイムアウト
時間、抽象プラン 165
探索引数
インデックス 11
最適化の例 12
作成 18
推移閉包 8
変換 7
ち
逐次
union all 57
スカラ集合 55
逐次テーブル・スキャン 45
中カッコ {}、SQL 文内 xii
抽出
SQL テーブル 19
抽象プラン 161
15.0 より前のオペレータのサポート
新しいディレクティブ 165
オペレータ 162
オペレータの仕様 193
構文 162
構文上の修飾 168
構文、新規 165
最適化タイムアウト時間 165
最適化目標 165
測定基準 167
古くなった部分プラン 169
ワーク・テーブルと手順 167
165
Adaptive Server Enterprise
索引
チューニング
オブジェクトのサイズに応じて
調整
管理、実行時 86
削減、実行時 87
識別、実行時 86
19
つ
追加
インデックス未設定カラムの統計値
173
インデックス未設定カラムの追加
カラム統計値の作成 184
カラムレベル 183, 184, 185
更新 173, 184
サンプリング 175
自動 update statistics 179
自動的な更新 176
使用 171
スキャン・タイプ 187
ソート条件 187
追加 185
ロッキング 187
統計値の追加 173
173
て
ディレクティブ、新規
抽象プラン 165
データ型
ジョイン 14
テーブル・スキャン
逐次 45
パーティションベース
ハッシュベース 46
並列 46
並列処理 44
は
46
と
パーティション
スキュー 83
テーブル・スキャン 46
パーティション排除 82
パーミッション
XML 153
廃止になったトレース・コマンド
XML 153
排除
パーティション 82
パイプ管理
exchange 39
ハッシュベース・テーブル・スキャン
46
度
最大並列度の設定 30
等価ジョイン
推移閉包 8
統計情報の更新
サンプリングの使用 175
統計値
datachange 関数 177
delete statistics による、テーブルとカラムの
削除 190
drop index 183
Job Scheduler の使用 179
truncate table 183
update statistics 174
インデックス未設定カラムのソート 188
クエリ・プロセッサ
ひ
ヒストグラム
ジョイン 13
ステップ、数 186
非先行カラム
統計値のソート 188
ビュー
sysquerymetrics、クエリ処理測定基準
表記規則
「構文」参照
Transact-SQL 構文 xi
リファレンス・マニュアル xi
157
257
索引
ふ
複合インデックス
update index statistics 185
不等号
演算子 12
プラン
クエリ 90
古くなった部分、抽象プラン
古くなった部分プラン
抽象プラン 169
文レベル出力 91
逐次ベクトル集合 70
テーブル・スキャン 44
複写ジョイン 63
分割済みベクトル集合 67
ベクトル集合 67
有効化 29
ワーカー・プロセス数の設定
並列度
max scan parallel degree の設定
ベクトル集合 67
2 フェーズ 69
distinct 71
再分割 68
逐次 70
分割済み 67
ベクトル集合オペレータ 127
変換
探索引数 7
変形
クエリの最適化 7
述部 10
変数
ローカル変数の設定 35
169
へ
並列
union all 56
クエリ実行モデル 38
クエリ処理 27
クエリ・プラン 36
最大並列度の設定 30
設定、max resource granularity 30
テーブル・スキャン 46
並列クエリの結果の変化 34
並列処理 17
2 フェーズ・ベクトル集合 69
distinct ベクトル集合 71
IN リストを持つクエリ 71
OR 句を持つクエリ 72
order by 句を持つクエリ 74
SQL 演算 43
外部ジョイン 67
クエリ 28
クエリの並列処理の制御 34
再フォーマット 64
再分割ベクトル集合 68
ジョイン 58
ジョイン、一方のテーブルの分割が有用 59
ジョイン、両テーブルの分割が有用でない 61
ジョイン、両テーブルの分割方式が同一で有用
セッション・レベルでの制御 32
セミジョイン 67
属性の影響を受けない演算 44
属性の影響を受ける演算 58
逐次ジョイン 66
258
29
31
ほ
方法
最適化
4
ま
マイナー・カラム
update index statistics
185
み
58
密度
ジョイン
13
め
メンテナンス
統計値 183
Adaptive Server Enterprise
索引
も
目標
最適化 15
最適化、例外 16
問題
クエリの最適化 18
ゆ
有効化
並列処理
29
よ
要素
最適化において分析される
6
れ
例外
最適化目標
16
ろ
ロー・カウント
統計値、不正確
ロッキング
統計値 187
191
わ
ワーカー・プロセス
数の設定 29
ワーカー・プロセス・モデル
exchange 40
ワーク・テーブル
抽象プラン 167
クエリ・プロセッサ
259
索引
260
Adaptive Server Enterprise
Fly UP