分12クエリのパフォーマンスを決める実行計画を見てみようさて,こうして実行計画が作られると,DBMSはそれをもとにしてデータアクセスを行います。データ量の多いテーブルへアクセスしたり,複雑なクエリを実行する場合,クエリのレスポンスが遅いことがよくあります。この理由には,先述のように統計情報が不正確であるという原因もありますが,それ以外にも,そもそも現状で最適なアクセスパスが選択されているのに遅い,ということもあります。統計情報は最新でも,クエリが複雑過ぎてオプティマイザが最適なアクセスパスを作成できないこともあります。した理由からクエリの遅延が発生したとき,最初に調べるべき対象が実行計画です。DBMSはいずれも,実行計画を調べる手段を提供しています。これから,次の3つの実行計画を見ていきましょう。実行計画を確認する手段は実装によって違いますが,多くのDBMSがコマンドラインのインタフェースから確認するためのコマンドを用意しています(表2⁠)⁠。Serverでは,上記コマンドのあとに対象のクエリを実行する具体的に,図2のようなサンプルテーブルを使うことにしましょう。ある業種の店舗についての評価や所在地域のデータを保存するテーブルだと考えてください。主キーは店舗IDで,テーブルには60行のデータを入れ,そのあとに統計情報を取得済みだとします。東京都まずは,レコードを全件取得するクエリの実行計画を見てみましょう。Shops;Oracle,PostgreSQL,MySQLの3つのDBMSで取得した実行計画を掲載します(リスト1~3⁠)⁠。|+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------+出力される情報のフォーマットは完全に同じではありませんが,すべてのDBMSに共通する出力項目があります。操作の対象となるレコード数」です。この3つは,それだけ重要な項目だということです。あと,MySQLは「table」列に,Shopsテーブルが出力されています。今はこの1つしかテーブルを使用していないため迷うことはありませんが,複数のテーブルを結合する場合,どのオブジェクトに対する操作なのかを混同しないように注意してください。この項目にはテーブル以外にも,インデックスやパーティション,シーケンスなど,SQL文でアクセス対象となるオブジェクトなら何でも現れます。オブジェクトの操作オブジェクトに対する操作は,実行計画で最も重要な項目です。Oracleの「Operation⁠」⁠,PostgreSQLの文頭,MySQLの「select_type」および「type」列からわかります。今,3つのDBMSは同じアクセス操作,すなわちシーケンシャルスキャンを実施しています。Scanは「シーケンシャルスキャン」の略です。OracleとMySQLの出力情報は,「⁠テーブルのデータを全部読み込みます」ということしか言っていないため,正確にはこれをシーケンシャルスキャンと同義と取るのは,レイヤを混同しています(注4⁠)⁠。PostgreSQLとは,出力レベルが違うということです。実際のところ,テーブルへのフルアクセスにはほとんどの場合,シーケンシャルスキャンが実施されます。DBMSはランダムスキャンも選択肢として持ちますが,このサンプルではテーブルのレコード数が少なく,またすべてのレコードを選択するクエリを実行していることから,シーケンシャルスキャンが選択されています。注4)たとえばOracleで,あるクエリがシーケンシャルアクセスを行っているかどうかを調べるためには,さらに一歩踏み込んで当該クエリのイベント情報まで調べる必要があります。操作の対象となるレコード数3つ目の重要な項目は,操作の対象となるレコード数です。これらはいずれも「Rows」の項目に出力されるため,わかりやすいでしょう。結合や集約が入ってくると,1つのクエリを実行するためだけでも,複数の操作が行われます。すると,各操作でどれだけのレコードが処理されるかが,クエリ全体の実行コストを把握するために重要になります(注5⁠)⁠。1実行計画で重要な項目は,オブジェクト,操作,レコード数の3つレコード数はテーブルの実件数と一致するとは限らないなお,この件数について1つ誤解してほしくないことがあります。それは,この数値が取得されている情報源についてです。先ほど「クエリが処理される流れ」でオプティマイザが実行計画を作る過程を解説した際にも説明したように,オプティマイザはテーブル情報をカタログマネージャから受け取ります。ここに出ている件数は,統計情報として取得された値がもとになっています。いま現時点のテーブルの実件数を示すものではないのです。ためしに,このShopsテーブルから全レコードを削除して(もちろんコミットもして⁠)⁠,それから再度実行計画を取得したらどうなるでしょう。実際にやっていただければわかりますが,3つのDBMSすべてについて,やはりRowsの項目には「60」という値が出力されます。オプティマイザは,あくまで統計というメタ情報を頼りにしていて,実テーブルなんか見ていないのです(注6⁠)⁠。注5)これに比べて,OracleやPostgreSQLの出力に含まれる実行コスト(cost)という指標は,あくまで筆者の経験上ですが,あまり役に立ちません。一見するとこの数値を減らすことが良いことのように思えますし,それも間違いではないのですが,どういうアルゴリズムで計算されているか不明なうえ,値の大小についても絶対評価ができないからです(たとえば「このクエリはcostが5,000しかないので1秒以内で終わるでしょう」という予測はできない⁠)⁠。注6)「そんな不正確なことしなくても,クエリ実行時にテーブル件数を数えるJIT処理をすればいいのに」と思うかもしれませんが,もし100万件オーダーのレコードが入っていた場合,rowsの値を取りにいくだけでも延々待たされてしまうことになります。クエリ評価エンジン著者プロフィールミックSI企業に勤務するDBエンジニア。データウェアハウス業務に従事している。自身のサイト「リレーショナル・データベースの世界」でデータベースとSQLについての技術情報を公開している。Press』で「SQLアタマアカデミー」を連載中。2019」を開催しました。DAY1・DAY2の様子を注目セッションとともにお伝えします。LINEのエンジニア3名がイベントに先駆けて見どころを紹介します。コードの安全性・安定性を高める開発サイクル~テスト管理の効率を上げ,脆弱性診断を自動で行う~本連載では,連載「業務を改善する情報共有の仕掛け」を受けつつ,安全性・安定性を加えた開発サイクルについて考えていきます。若者世代から圧倒的な人気を誇るライブ配信&動画投稿コミュニティアプリ「MixChannel」(ミクチャ)の裏側(レコメンドシステムやサーバサイド開発など)について解説していきます。その他の連載CSS3アニメーションでつくるインターフェイス表現CSS3によるアニメーション表現を紹介していきます。その中でも,幅広い読者に応用してもらえるだろうインターフェイスを主なお題とします。MySQL道普請便り本連載では,MySQLを使ったアプリ開発・運用に関するノウハウをご紹介していきます。RecipeUbuntuの強力なデスクトップ機能を活用するための,いろいろなレシピをお届けします。JavaScriptセキュリティの基礎知識JavaScriptに関するセキュリティ上の問題はどこで発生し,どうすれば防ぐことができるのか?について解説していきます。〜システムをきちんと運用するための基礎知識システムは「作って終わり」ではなく,運用の中でさまざまな問題が発生します。問題の発生に備えて事前にどのような対応をしておくべきなのか,問題発生時に何をしなければならないのか,ポイントを解説していきます。きたみりゅうじの聞かせて珍プレーソフトウェア開発の現場で体験したトホホな失敗,思わずうなる珍プレーをきたみりゅうじ氏が四コママンガで紹介。Linuxのメンテナンスの傍ら,Linuxやオープンソースソフトと日々を過ごす著者が,その魅力とつきあい方を,エッセイ風味でお届けします。PRESS特別編集部員,さわやか笑顔のスーパーハカーはまちちゃんとネット大好き14歳わかばちゃんが,毎号,読者の皆さんから寄せられたおたよりを紹介します。皆さんの日頃の悩みにも答えちゃいますよ。]メールでのお知らせメールで次の案内をお送りしております。メールの配信を希望する方は,利用したい項目をチェックしてメールアドレスを入力し,[登録]ボタンをクリックしてください。UPDATES[ほぼ週間に1回]新刊メールマガジン[ほぼ週間に1回]電脳会議の各号案内[ほぼ1ヵ月半に1回]※変更する場合や停止する場合は,登録情報変更ページをご覧ください。※登録いただいたメールアドレスには,そのお知らせ以外,配信いたしません。Ltd.ページ内容の全部あるいは一部を無断で利用することを禁止します。個別にライセンスが設定されている記事等はそのライセンスに従います。