今だけ人気マンガ100円レンタル特集♪

こんにちは、honiyonです。

  2つのテーブルを参照して結果を問い合わせるSQLについて質問です。

SELECT * from A,B where ((A.ID=B.ID) and (A.DAT1=1)) and (A.Kind=1) and (A.Open=1) order by A.hoge;

  で問い合わせると返ってくるまで数秒時間がかかります。
  しかし、

SELECT * from A,B where ((A.ID=B.ID) and (A.DAT1=1)) and (A.Kind=0) and (A.Open=0) order by A.hoge;

  で問い合わせると瞬時に返ってきます。

  双方とも検索結果は0件です。
  検索処理の条件は同じはずなのに・・・と思うのですが。
  どんな理由が考えられるでしょうか?また、高速化するにはどんな対策があるでしょうか?

  因みに、A.ID,B.IDはcharで、DAT1,Kind,Openはintです。

  distは、Vine2.5, DBは、PostgreSQL 7.2.3です。
  宜しくお願いします(..

このQ&Aに関連する最新のQ&A

A 回答 (2件)

PostgreSQLについて無知なので一般論として。



INDEXは指定されてないものとして
SQLの条件文が複数指定された場合前から評価するものと後ろから評価するものの
2パターンがあります。
で、使ってるDBにあわせて一番最初に評価される条件式で対象データを一気に絞ります。

仮に前から条件が評価されるとしたら、前2つの条件式は同じなので("A.ID=B.ID" "A.DAT1=1")
3番目の "A.Kind="の対象件数が大きく違うのではないでしょうか?
A.Kind=1の条件に合うのが1000件でA.Kind=0が1件なら次の"A.Open=?"の評価対象が1000倍違いますので
その差がトータルの問い合わせ時間の差になります。

検索方法とINDEXを張る項目がポイントです。
    • good
    • 0

データベースは実際の結果を作成する前にSQL文の最適化を行うそうです。


PostgreSQLでもEXPLAINというコマンドが用意されていますので
それで実際に行われている問い合わせの実行計画を見ることができますので
両方のSQL文でどういった最適化が行われているのか
比較してみると何かヒントになるかも知れません

参考URL:http://www.postgresql.jp/document/pg721doc/refer …

この回答への補足

こんにちは、honiyonです。
  sheepsさん、Paul_xxxさん、ご回答有難う御座います(..

  お礼が遅れ申し訳ありません。
  有効なご回答を頂いたにも関わらずこちらを試す時間が作れないでいます...

  ひとまず一旦質問を締め切ります。
  後日試してそれでも分からないようであれば再度質問させて頂きます。

  有難う御座いました(..

補足日時:2002/11/28 16:34
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QInner join と Left joinの明確な違いは?

Inner join と Left joinの違いがよくわかりません。
教えてください。

Aベストアンサー

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
4               NULL
5               NULL
6               NULL
の6レコードが出力されますが、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 INNER JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
の3レコードしか出力されません。

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3           ...続きを読む

Q外部結合と等価結合のパフォーマンスの違いについて(ビューの場合)

Oracle10gでのSQL文の違いについて教えて下さい。

前回の質問は、ストアドプロシージャに記述
されていて、バッチとして動かしています。
と書きましたが、ビューの場合のパフォーマンスの違いは
どうなるのでしょうか?ビューの場合も同じような現象です。
下記の2つのSQL文は外部結合ありと外部結合なしの違いだけで、
他は変わりありません。
外部結合ありのほうは
結果がすぐに返されるのですが、外部結合なしのほうは
結果が返ってこない、あるいはかなり時間がかかるという
現象が起きています。
SQL文は簡略して記述していますが、SELECT句には、
TO_CHAR()やSUM(CASE WHEN ...THEN ...ELSE...)が使用してあり
少し重くなる処理も含まれています。
この2つのSQL文でパフォーマンスに影響している原因は
何なんでしょうか?オプティマイザとか実行計画とかの
説明を読んだのですが、いまいちよく解りません。。
自分では中級者以下だと思っていますので、わかりやすく
説明して頂けたら助かります。宜しくお願い致します。

(外部結合ありのSQL)
SELECT
 a.項目1,
 a.項目2,
 a.項目3,
 a.項目4,
 a.項目5
FROM
 TBL_A a,
 TBL_B b
WHERE
 a.項目1 = b.項目1(+) AND
 a.項目2 = b.項目2(+) AND
 a.項目3 = b.項目3(+) AND
 a.項目4 = b.項目4(+) AND
GROUP BY
 a.項目1,
 a.項目2,
 a.項目3,
 a.項目4,
 a.項目5

(外部結合なしのSQL)
SELECT
 a.項目1,
 a.項目2,
 a.項目3,
 a.項目4,
 a.項目5
FROM
 TBL_A a,
 TBL_B b
WHERE
 a.項目1 = b.項目1 AND
 a.項目2 = b.項目2 AND
 a.項目3 = b.項目3 AND
 a.項目4 = b.項目4 AND
GROUP BY
 a.項目1,
 a.項目2,
 a.項目3,
 a.項目4,
 a.項目5

Oracle10gでのSQL文の違いについて教えて下さい。

前回の質問は、ストアドプロシージャに記述
されていて、バッチとして動かしています。
と書きましたが、ビューの場合のパフォーマンスの違いは
どうなるのでしょうか?ビューの場合も同じような現象です。
下記の2つのSQL文は外部結合ありと外部結合なしの違いだけで、
他は変わりありません。
外部結合ありのほうは
結果がすぐに返されるのですが、外部結合なしのほうは
結果が返ってこない、あるいはかなり時間がかかるという
現象が起きています...続きを読む

Aベストアンサー

オラクルのオプティマイザは、テーブルの検索の方法を決めますが、外部結合と内部結合で
立案される実行計画に違いがあり、内部結合の方が合理的な検索方法を立案しているので
結果的に、内部結合の方が速いという話なんですが・・

実行計画を見なければ、判りませんが、
・外部結合はbに対して全表検索を選択した。
・内部結合では、bを索引検索を選択した。
・bの検索量が、bの格納件数のうち、ごく一部なので、全表検索と索引検索では、極端に検索時間が違う。
ということなんだと思います。(推測なので、実は違うかも知れません)

オラクルのマニュアルで、パフォーマンスチューニングガイドというマニュアルがあると思うので、
一読されることをお勧めします。


ちなみに、お書きになったSQLは何か変です。
内部結合のSQLは、bの項目を返さないので、実質的にbに存在するかのチェックを行っているに等しいものです。
書き方や流儀の問題で、内部結合が良いのか、exists条件が良いのか、in条件(メンバーシップ検査)が良いのか
変わってくると思いますが、一応理解できるものです。
しかし、外部結合のSQLについては、bを検索するけど、何もしない??理解に苦しむSQLになっています。
基本的に、内部結合より遅くなる外部結合を、わざわざ書いてみた、というように感じます。
(一般論ですが、同じ書き方をしたら、外部結合は内部結合と同等以下です)

オラクルのオプティマイザは、テーブルの検索の方法を決めますが、外部結合と内部結合で
立案される実行計画に違いがあり、内部結合の方が合理的な検索方法を立案しているので
結果的に、内部結合の方が速いという話なんですが・・

実行計画を見なければ、判りませんが、
・外部結合はbに対して全表検索を選択した。
・内部結合では、bを索引検索を選択した。
・bの検索量が、bの格納件数のうち、ごく一部なので、全表検索と索引検索では、極端に検索時間が違う。
ということなんだと思います。(推...続きを読む

QLEFT JOINが2つあるSQL文でANDの意味

■下記SQL文の意味を教えてください

SELECT a.*, b.being_name
FROM alive a
 LEFT JOIN being b ON a.hoge_id = b.id
 LEFT JOIN call c ON c.call_id = a.hoge_id
  AND f.hoge_id = 12
 WHERE f.hoge_id = 12 OR b.id = 12

※12の部分は動的に切り替わります

・LEFT JOINが2つあるので、3つのテーブルを結合しているのでしょうか?
・左テーブルは「alive a」で、この右側に2つのテーブルが結合している、という認識でよいでしょうか?

>SELECT フィールド名 FROM テーブル名 WHERE 条件式1 AND 条件式2
>「AND」は2つの条件式の論理積
・上記内容をネットで見かけたのですが、「AND」は、「WHERE」の前に来てもいいのでしょうか? それともこのSQLの「AND」は違う使い方をしているのでしょうか? 何か、LEFT JOINに関係しているのでしょうか?

■下記SQL文の意味を教えてください

SELECT a.*, b.being_name
FROM alive a
 LEFT JOIN being b ON a.hoge_id = b.id
 LEFT JOIN call c ON c.call_id = a.hoge_id
  AND f.hoge_id = 12
 WHERE f.hoge_id = 12 OR b.id = 12

※12の部分は動的に切り替わります

・LEFT JOINが2つあるので、3つのテーブルを結合しているのでしょうか?
・左テーブルは「alive a」で、この右側に2つのテーブルが結合している、という認識でよいでしょうか?

>SELECT フィールド名 FROM テーブル名 WHERE 条件式1 AND 条件式...続きを読む

Aベストアンサー

>・LEFT JOINが2つあるので、3つのテーブルを結合しているのでしょうか?
はいそうです。

>左テーブルは「alive a」で、この右側に2つのテーブルが結合している、という認識でよいでしょうか?
はいそうです。(alive→beingって言うような意味です。)

>・上記内容をネットで見かけたのですが、「AND」は、「WHERE」の前に来てもいいのでしょうか?
「AND]は「WHERE」にかかっているのではなく「LEFT 」の結合の条件となります。
SELECT a.*, b.being_name
FROM alive a
LEFT JOIN being b ON a.hoge_id = b.id
LEFT JOIN call c ON (c.call_id = a.hoge_id AND f.hoge_id = 12)
WHERE f.hoge_id = 12 OR b.id = 12

<<追記>>
このSQLにはfというテーブルが存在しないのでエラーとなります。

Q外部結合のパフォーマンスチューニングできますか

下のSQL文がパフォーマンスが非常に悪いです。
何かチューニングする方法ありませんか。

Oracle8.1.7 
OSはWin2000serverSP2

◇SQL文
SELECT A.HINCD , B.TANCD ,A.SIZE,A.COLOR
FROM TB_TBLA A ,TB_TBLB B
WHERE A.KA_CD = B.KA_CD(+)"
AND A.HINCD = B.HINCD(+)
AND A.JIGYOCD = 1
AND A.BRCD = 20
AND A.BUCD = 300

TB_TBLAの主キーは、JIGYOCD、BRCD、BUCDです。
TB_TBLBの主キーは、KA_CDです。

また、TB_TBLAの件数は、約10万件、TB_TBLBは3万件だとしたら、
読み込み件数は10万*3万件となるのでしょうか。

よろしくお願いします。

Aベストアンサー

>"iniSID.ora”の中の”SORT_AREA_SIZE”を変更するような感じで色々書いてあるのですが、iniファイルには”SORT_AREA_SIZE”たる記述がありません。
初期化パラメータファイル(init.ora)にありませんか。
ただ初期化パラメータの「sort_area_size」を大きめに変更する場合、同時に「sort_area_retained_size」も変更しないと意味がないかと思います。

それと、init.oraを変更して、Oracleを再起動する野は大変ですよね。
ALTER SESSION SET SORT_AREA_SIZE=値;で設定していろいろ試してから変更するほうがらくだと思います。

QPostgreSQLで外部DB内のテーブル参照方法を教えてください

PostgreSQLで別データベースのテーブルを参照することはできますか?

仮に以下のデータベースが2つあるとします
CREATE DATABASE common_db ...
CREATE DATABASE app1_db ...

app1_db に接続した状態で common_db のテーブルを参照することはできますか?

仮にcommon_dbに郵便番号テーブル postcodeがあるとします
CREATE TABLE postcode (
postcode text, --郵便番号
pref_name text, -- 県名
 ・・・
)

このpostcodeテーブルをapp1_dbに接続した状態で参照するには、どのような参照クエリになりますか?
ご教授の程よろしくお願います。
そもそもできないのでしょうか?

Aベストアンサー

PostgreSQL 本体の機能では実現できませんが、contrib モジュールの dblink を使えばできます。

dblink のインストール方法は PostgreSQL のインストール方法によって異なりますが、RPM パッケージであれば postgresql-contrib というパッケージをインストールし、以下のように dblink の関数などを定義します。

psql -f /usr/share/postgresql/contrib/dblink.sql (データベース名)

データベース名には他のデータベースにアクセスしたいデータベース名、例では app1_db を指定します。なお、dblink.sql のパスはパッケージによって異なる場合があります。

dblink をインストールすれば以下のように関数を呼び出して別のデータベース内のテーブルを参照できます。

SELECT * FROM dblink('dbname=common_db', 'SELECT * FROM postcode') AS postcode(postcode text, pref_name text);

dblink について詳しくは PostgreSQL のマニュアルを読んでください。

http://www.postgresql.jp/document/pg840doc/html/dblink.html

ただ、質問の例にあるデータベース名やテーブル名を見ていると、アプリケーションごとに名前空間を分けたいだけのようなので、それであればスキーマを使ったほうがよさそうな気もします。

参考URL:http://www.postgresql.jp/document/pg840doc/html/dblink.html

PostgreSQL 本体の機能では実現できませんが、contrib モジュールの dblink を使えばできます。

dblink のインストール方法は PostgreSQL のインストール方法によって異なりますが、RPM パッケージであれば postgresql-contrib というパッケージをインストールし、以下のように dblink の関数などを定義します。

psql -f /usr/share/postgresql/contrib/dblink.sql (データベース名)

データベース名には他のデータベースにアクセスしたいデータベース名、例では app1_db を指定します。なお、dblink.sq...続きを読む

QPOSTGRESのデータの格納場所はどこでしょうか?

RedHat7.2/PostgreSQL7.2/という環境で、サーバーがクラッシュしてしまい、データを他のサーバに移し変えないといけなくなりました。そこで、PostgreSQLを再インストールしないとデータベースが使えない状況となりました。

データベースを再インストールするのは良いとして、どこかに格納されているはずのデータベースの内容を取り出し、復帰させたいのですが、方法はありますか?大変困っております。よろしくお願いします。

Aベストアンサー

No.1の追加です。
データの移設でよかったと思います。
または、データを読み込むときに、「iオプション」でディレクトリを指定して、元のファイルを読み込んでもよかったと思います。

QViewにインデックスは張れますか?

件名の通りなのですが、作成したViewが遅くて困っています。
改善方法としてはViewを作成しないで従来のSQLにインデックスを張って取得する方法にしようかなと考えています。
なにかいい方法はありますか?

Aベストアンサー

Viewの元テーブルに適切なIndexを貼る、ではいけないのですか?

Q2回目のselect文

同じselect文でも
1回目のselect文と2回目のselect文の早さが全然違います。
なぜでしょう?

Aベストアンサー

一般的には2回目の方が早くなります。
理由は、1回目はHDD上のテーブルから情報を読みますが、この時メモリー上にキャッシュされます。
2回目はメモリー上にキャッシュされた情報を読むので、HDDを読まない分早くなります。

Qcastの使用法について(初心者です)

始めまして。初心者ですので基本的な質問になるかもしれませんがよろしくお願いします!

なぜかPostgreSQLを仕事に使うことになり、四苦八苦しています。

テーブルを作成しているときに、
create table syouhin (shinamono text, nedan int);
とするとします。
で、insert でデータを入れていきますが、
例:
shinamono | nedan
------------------
みかん |100
マンゴー |200

例えば、nedan のcast が今、int にしましたが、これをchar やfloatに変えたいときはどうすればよろしいのでしょうか?

どなたか御存じの方、お手数ですがお教え下さい!!!

Aベストアンサー

CAST関数の文法は、CAST(○ AS △) となります。
○:変換する値
△:変換する型

Select CAST(nedan AS char(10)) ~
とすればできると思いますよ

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分


人気Q&Aランキング