SQLの相関副問い合わせについての質問です。


一般的にプログラム内で使用するSELECT文にアスタリスクは使用しませんが
EXISTSを使用したサブクエリの場合はどうなんでしょうか?
EXISTSのサンプルには、サブクエリ内に 大抵SELECT * が使われているようです。

EXISTSを使ったサブクエリ内で * を使う場合、使わない場合でのメリットデメリットを教えてください。

よろしくお願いします。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2009/10/29 19:10:47
  • 終了:2009/11/05 19:15:02

ベストアンサー

id:khazad-Lefty No.3

khazad-Lefty回答回数181ベストアンサー獲得回数272009/10/30 07:10:02

ポイント26pt

MS-SQLServer使いです。実機が手元にないので感覚的な話になりますが。

まず、ある程度質のいいオプティマイザであれば、

Existsがある時点で、*が指定されても全部の列を確認するわけではなくて、

「行があるか」のみを確認しに行くはずです→count(*) と同じ

メリット

  • 可読性:ExistsならSelectの列に意味はないので、文字は少ないほうが読みやすいし、いちいち列の有無を意識する必要がない。
  • パフォーマンスの安定性:ExistsのSelect列にインデックスのない列を明示的に指定するとテーブルスキャンになる可能性がある?

デメリット

  • 古いDBエンジンだとテーブルスキャンになる可能性がある。

http://www.geocities.jp/mickindex/database/db_optimize.html#Loca...

id:yocchi24

なるほど、ありがとうございます。

私もほぼ同様の認識でおります。

ただ、それが記載されている情報ソースがみあたらなくて…何かご存知でしたら教えてください。

2009/10/30 10:23:21

その他の回答(2件)

id:sirotugu40 No.1

sirotugu40回答回数449ベストアンサー獲得回数142009/10/29 19:58:11

ポイント27pt

>EXISTSのサンプルには、サブクエリ内に 大抵SELECT * が使われているようです。


EXISTSの場合は、レコードのチェックをするだけで実際にはデータを読み込まないので

*でもそうでなくても同じです。

http://q.hatena.ne.jp/answer

id:yocchi24

ありがとうございます。

私もそういった認識ではいるのですが

情報ソースがどこかにあるでしょうか?

2009/10/30 10:24:29
id:b-wind No.2

b-wind回答回数3344ベストアンサー獲得回数4402009/10/29 20:25:55

ポイント27pt

EXISTSを使ったサブクエリ内で * を使う場合、使わない場合でのメリットデメリットを教えてください。

機能上は特に差はない。


ただし、RDBMS の実装によっては速度に差が出る場合がある。

2つの副問い合わせの違い - オラクル・Oracleをマスターするための基本と仕組み

ちなみに、EXISTS の中の 副問い合わせには、'SELECT * FROM ~'を使用するより 'SELECT 1 FROM ~' などの固定項目を使用した方が早い

MySQL :: MySQL 5.1 リファレンスマニュアル :: 12.2.8.6 EXISTS と NOT EXISTS

もともと、EXISTS サブクエリは SELECT * で開始しますが、SELECT 5 や SELECT column1、またそれ以外のどんな物でも開始する事ができます。MySQL はそのようなサブクエリの中では SELECT リストを無視するので、何も変わらないのです。

id:yocchi24

ありがとうございます。

参考リンクは私も拝見してましたが、古い情報なのかなぁと思っていました。

今でも変わらないでしょうか?

2009/10/30 10:19:19
id:khazad-Lefty No.3

khazad-Lefty回答回数181ベストアンサー獲得回数272009/10/30 07:10:02ここでベストアンサー

ポイント26pt

MS-SQLServer使いです。実機が手元にないので感覚的な話になりますが。

まず、ある程度質のいいオプティマイザであれば、

Existsがある時点で、*が指定されても全部の列を確認するわけではなくて、

「行があるか」のみを確認しに行くはずです→count(*) と同じ

メリット

  • 可読性:ExistsならSelectの列に意味はないので、文字は少ないほうが読みやすいし、いちいち列の有無を意識する必要がない。
  • パフォーマンスの安定性:ExistsのSelect列にインデックスのない列を明示的に指定するとテーブルスキャンになる可能性がある?

デメリット

  • 古いDBエンジンだとテーブルスキャンになる可能性がある。

http://www.geocities.jp/mickindex/database/db_optimize.html#Loca...

id:yocchi24

なるほど、ありがとうございます。

私もほぼ同様の認識でおります。

ただ、それが記載されている情報ソースがみあたらなくて…何かご存知でしたら教えてください。

2009/10/30 10:23:21
  • id:b-wind
    > 参考リンクは私も拝見してましたが、古い情報なのかなぁと思っていました。
    > 今でも変わらないでしょうか?
    当然実装次第なので速度自体はバージョン等によって変わる。
    直接は見つけられなかったので紹介しなかったが PostgreSQL/MySQL あたりでチューニングの結果速度向上が行われた記憶がある。

    固定値の方が良い実装もあるし、「*」の場合のみに最適化を行うオプティマイザもある。
    一般論は何も言えない状況なので実際に最新のマニュアルを参照するならり、実行してみる方がいいかもしれない。

    もちろん SQL としては等価なので実行結果自体には影響は無いが。
  • id:yocchi24
    ありがとうございます。そうなんです。紹介している記事がなかなか見つけられなくて…。

    Count関数でもそうですが、カラム指定を許してしまうとindexがついてないカラムを使って
    記述する人がでてきそうなので、大差がないのであればアスタリスクを使うように指定してしまいたいです。

    また他の方もご回答されているように、行の有無を確認するだけなので列は関係ないという説もよくききます。
    調査してみると、b-windさんのような回答もあり、どちらがよいのか迷っているしだいです。

    本当は自分で調査できるのがいいのでしょうが…。

    >PostgreSQL/MySQL あたりでチューニングの結果速度向上が行われた記憶がある。

    MySQLの場合、Oracleのrowidに匹敵するものはないので、PostgreSQLかもしれないですね。
  • id:b-wind
    > Count関数でもそうですが、カラム指定を許してしまうとindexがついてないカラムを使って
    count 関数においてはカラム指定をすると該当カラムが NULL 以外のレコードをカウントする。
    アスタリスク指定と意味が違うので例として適切ではないし認識を改めるべき。

    > MySQLの場合、Oracleのrowidに匹敵するものはないので、PostgreSQLかもしれないですね。
    MySQL にもそれに類する物はあるし、オプティマイザがどう解釈するかなので本質問には直接関係はない。

    http://www.geocities.jp/mickindex/database/db_optimize.html#LocalLink-aster
    いろいろなところで引用されているようだが推奨される書き方としてはアスタリスク指定となるはず。
  • id:yocchi24
    > count 関数においてはカラム指定をすると該当カラムが NULL 以外のレコードをカウントする。
    > アスタリスク指定と意味が違うので例として適切ではないし認識を改めるべき。
    "行を数える場合には"って書き漏らしていて、わかりづらかったようですね。

    > http://www.geocities.jp/mickindex/database/db_optimize.html#LocalLink-aster
    > いろいろなところで引用されているようだが推奨される書き方としてはアスタリスク指定となるはず。

    なるほど。いろいろご丁寧にありがとうございます。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません