• ベストアンサー

INDEXの仕様

PostgreSQL8.1.1(RedHatLinux)にて テーブルのtext列に対してindexを作成しました。 作成した列に対して、LIKE検索を行っております。 しかし、「EXPLAIN」を利用してSQLの実行計画を見たんですが、 「Seq Scan」からしか始まらず、 「Index Scan」という文字が見当たりません。 PostgreSQLにてindexを張った列に対するLIKE検索では、 indexは使用されないのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

マニュアルに「前方一致('abc%'等)でないと、インデクスは使用しない」と明記されています。

参考URL:
http://www.postgresql.jp/document/pg823doc/html/indexes-types.html
susumufire
質問者

お礼

早速のご回答ありがとうございます。 マニュアルに書いてありましたか・・・ 読み落としました。 前方一致ができないとなると、 別の方法を考えたいと思います。

その他の回答 (1)

  • moritan2
  • ベストアンサー率25% (168/670)
回答No.1

likeでどんな検索をされましたか? 'xxx%'ならインデックスが使えるけど、'%xxx'だとできないと思いますよ。

susumufire
質問者

お礼

早速のご回答ありがとうございます。 LIKE検索で中間一致('%hoge%')を使用しております。 前方一致で利用できないとなると、 中間一致でもできそうにないですね。

関連するQ&A

  • 前方一致が動的に変更される場合にINDEXは有効になりません。

    いつもお世話になっております。 テーブル同士のLIKE検索(前方一致)を行った場合、 INDEXが有効になりません。 LIKE検索文字列を固定にした場合は、INDEXが有効 になります。 テーブル同士のLIKE(前方一致)でINDEXを 有効にする手段をご教授頂けないでしょうか。 以下、実行結果です。 (1)LIKE検索文字列が固定 ---------------------------------------------------------------------------- EXPLAIN SELECT * FROM wk_dss_data WHERE sys_id LIKE 'M004964%'; ---------------------------------------------------------------------------- Index Scan using i_wk_dss_data_02 on wk_dss_data (cost=0.00..5.25 rows=1 width=311) Index Cond: (((sys_id)::text >= 'M004964'::character varying) AND ((sys_id)::text < 'M004965'::character varying)) Filter: ((sys_id)::text ~~ 'M004964%'::text) (2)テーブル同士のLIKE検索 ---------------------------------------------------------------------------- EXPLAIN SELECT wk_dss_data.comp_id, wk_dss_data.user_id FROM wk_dss_data, t_update WHERE wk_dss_data.sys_id LIKE t_update.sys_id||'%'; ---------------------------------------------------------------------------- Nested Loop (cost=157.00..12505636.00 rows=2500000 width=20) Join Filter: (("outer".sys_id)::text ~~ (("inner".sys_id)::text || '%'::text) ) -> Seq Scan on wk_dss_data (cost=0.00..5479.00 rows=100000 width=31) -> Materialize (cost=157.00..207.00 rows=5000 width=11) -> Seq Scan on t_update (cost=0.00..157.00 rows=5000 width=11)

  • インデックスについて

    テーブルは2つ ・offacc_siwakedata ・off_projectmster とあり、それぞれ下記インデックスを張っております。 create index siwakedata_index ON offacc_siwakedata( siwakedata_date, siwakedata_hdcd, siwakedata_cd, siwakedata_kamokucode, siwakedata_projectcode, siwakedata_exzankada, siwakedata_default, siwakedata_compcd, siwakedata_del ); CREATE INDEX projectmster_index ON off_projectmster( projectmster_cd, projectmster_del, projectmster_compcd ); 2つのテーブルを結合させる下記SQLを発行 explain select offacc_siwakedata.*, off_projectmster.projectmster_name from offacc_siwakedata,off_projectmster where off_projectmster.projectmster_cd=siwakedata_projectcode and off_projectmster.projectmster_del='1' and off_projectmster.projectmster_compcd='200' and siwakedata_compcd='200' and siwakedata_del='1' and siwakedata_default='1' and siwakedata_kamokucode='26300' and siwakedata_exzankada<>0 order by siwakedata_date, siwakedata_hdcd, siwakedata_cd ; explainするとoff_projectmsterのインデックスが有効になっていません。 何ででしょうか? 教えてください。 宜しくお願いします。 "Nested Loop (cost=0.00..17438.04 rows=1 width=1307)" " Join Filter: ((off_projectmster.projectmster_cd)::text = (offacc_siwakedata.siwakedata_projectcode)::text)" " -> Index Scan using siwakedata_index on offacc_siwakedata (cost=0.00..17436.98 rows=1 width=1244)" " Index Cond: (((siwakedata_kamokucode)::text = '26300'::text) AND ((siwakedata_default)::text = '1'::text) AND ((siwakedata_compcd)::text = '200'::text) AND (siwakedata_del = 1))" " Filter: (siwakedata_exzankada <> 0::numeric)" " -> Seq Scan on off_projectmster (cost=0.00..1.04 rows=1 width=96)" " Filter: ((projectmster_del = 1) AND ((projectmster_compcd)::text = '200'::text))"

  • MySQLのインデックスについて

    MySQLのインデックスについて 以下のSQLにてお聞きしたいことがあります。 SELECT * FROM table1 WHERE num = '1' numはint型でインデックスを作成済の列なのですが、 問い合わせでは'1'のように文字列型で条件指定しています。 この場合、numに対するインデックスは効くでしょうか? よろしくお願い致します。 追伸 なぜこのような質問をさせて頂くかと申しますと、 私は開発環境でZend Frameworkを使用しておりまして、 その中のZend_Dbを使用しているのですが、 名前つきパラメータを使用してSQLを実行した場合に、 実際の実行されているSQLではどのパラメータも、 シングルクォーテーションで囲われているのではと思うんです。 以前、SQL実行に失敗して出力されたエラーメッセージの一部に、 実際に実行されたSQLが記述されていたのですが、 数値型の列もシングルクォーテーションで囲われていたんです。 もしかしたら名前つきパラメータを使用すると、 すべてのパラメータが文字列型扱いされているのではと思い、 こちらに投稿させて頂きました。

    • ベストアンサー
    • MySQL
  • indexを使おうとしない間違ったcost計算

    postgres 7.2.4で質問させてください。 以下のような構成のテーブルの抽出をしようとしています。 テーブル名 :t_name カラム名  :k1、k2、k3 インデックス:t_name_idx  テーブルt_nameの全体件数は約70万件で、上記のSQLから期待 される抽出結果件数は約1万5千件です。t_nameにはk3のみを対象としたインデックス、t_name_idxが作成してあります。次のようなSQLを実行した際に、シーケンス検索になり応答までに6秒ほどかかってしまいます。  select k1,k2 from t_name where k3 in ("100","200"); explain analyzeで実行計画を見ると (cost=26.29..15304.62 rows=523 width=104) Total runtime: 6427.32 msec です。シーケンスをSET enable_seqscan TO off; で使用しないようにして、強制的にt_name_idxを使うと次のような結果になります。 (cost=0.00..42009.05 rows=523 width=104) Total runtime: 423.81 msec 実際にはindexを使用したほうが10倍以上も速いのに、プランナはシーケンス検索のほうがコストが小さいと判断しています。何故このようになってしまうのでしょうか?VACUUM ANALYZEを行っても結果は変わりませんでした。 私のイメージでは、index検索のほうがコストが小さく計算されて、それを使うべき。というイメージなのですが、考え方自体が間違っているのでしょうか? 原因を調べ始めて1週間経ち、行き詰っています。 どなたかヒントだけでもいいので教えてください。

  • 実行プランの確認

    お世話になります。 SQL Server 2008 でテーブルを作成し、 クエリの実行プランを表示してみました。 条件に、プライマリーキー以外の項目を指定しても クラスターインデックススキャンになります。 私の記憶違いかと疑って、 SQL Server 2005 に同様のテーブルを作成し、 実行プランを表示したところ、 テーブルスキャンとなりました。 SQL Server 2008 から、必ずクラスターインデックス となったのでしょうか?

  • インデックスを使用して・・・

    おはようございます。 SQLServerのテーブルに格納された情報が多いので インデックスを用いて検索処理を早めたいと考えました。 ---テーブル構成-------------- name / varchar address / varchar age / int ---------------------------- name,addressフィールドにインデックスを指定したのですが、 インデックスを指定することにより検索するSQL文に なにか特別な書き方をしなくてはいけないのでしょうか? select name, address, age from test_table; ってSQLを記述しただけでは、 インデックスを作成する前と後では意味はないのでしょうか? 宜しくお願い致します。m(_ _)m

  • テーブル作成時にエラー?

    こんにちは。 以下のような環境で操作を行っています。 RedHatLinux9.0 PostgreSQL 8.0.3 テーブル作成時に次のようなメッセージが出力され、テーブルを作成することができません。 NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "PK_SIKYO" for table "TM_SIKYO" ちなみに実行したSQL文は次の通りです。 CREATE TABLE "TOUSHIN"."TM_SIKYO" ( "SHIKYO_CD" int4 NOT NULL DEFAULT nextval('"TOUSHIN"."TM_SIKYO_SHIKYO_CD_seq"'::text), "SHIKYO_NM" varchar(50), "SHIKYO_RNM" varchar(50), "SHOW_FLAG" bool, "UNUSE_FLAG" bool, "CREATE_DATE" timestamp DEFAULT ('now'::text)::timestamp(6) with time zone, "CREATE_ID" varchar(10), "CHANGE_DATE" timestamp DEFAULT ('now'::text)::timestamp(6) with time zone, "CHANGE_ID" varchar(10), CONSTRAINT "PK_SIKYO" PRIMARY KEY ("SHIKYO_CD") ) WITHOUT OIDS; SQL文はWindows版のPostgreSQLから作成したものを、そのままコピーして利用しました。 プライマリーキーが正しく設定できていないようなメッセージだと思うのですが、対処法など詳しいことが分からずに困っています。 Windows版から出力したSQL文なので、SQL文に間違いがありそうな感じでもないですし、一体何が原因なのでしょうか?

  • ■検索時にINDEX(インデックス)がどう役立つのか?

    いつもお世話になっております。 MySQLのカテゴリにて質問をさせて頂きますが、このことに意味はありません。 SQLにおける、INDEXの考え方を知ることができれば良いなと思っております。 SQLについては初心者ですので、分かりやすく教えて頂けると助かります。 では、本題へ。 ------------- あるデータテーブルの検索速度を上げる方法として、 INDEXを設定することもその1つに挙げられるかと思いますが、 あるテーブルにおける、ある列(フィールド)に対しINDEXを設定した場合、 検索時、それはどう利用されるのでしょうか、というのが質問です。 例えば、 会員データベース ・会員番号:id ・年齢:age ※その他、複数のフィールドを持つ、とする。 上記の会員データベースにおいて、 CREATE INDEX idx ON tbl_member(id); という風に、tbl_memberテーブルに対し、 会員番号(id)をINDEXに設定したとします、 idは唯一無二の(ユニークな)データです。 この会員テーブルにおいて、 年齢(age)フィールドをもとに、40歳以上の会員を抽出(検索)したい場合、 INDEX(idが設定されている)はこの検索において、 どういう仕組みで活かされることになるのでしょうか? ageと無関係のidが、どう役に立つのか分からずにいる、ということです。 ネット上で色々調べたのですが、 あるフィールドをINDEXに設定した場合に、 それが検索時にどう活かされるのかについて説明されているページを 私は見つけることができませんでしたので、質問させて頂きました。 どうぞ、宜しくお願い致します。

    • ベストアンサー
    • MySQL
  • MySQLでFullTextインデックスの再構築

    現在Webアプリを制作しています。 そこで検索機能を作成するにあたり FullTextで全文検索を行う処理を考えています。 Like文を使って検索するより速いらしいのですが、 insert/update文を実行しデータベースにデータを挿入/更新する際 FullTextで全文検索を行う場合だとインデックスを再構築する必要が あるみたいです。 http://melrose.jugem.cc/?eid=323 このインデックスの再構築についてよく分からないのですが、 上記のサイトではインデックスの再構築には REPAIR TABLE [テーブル名] QUICK; を実行とありました。 データの挿入/削除 処理後の検索インデックス修復には innsert 又は update文の直後にREPAIR TABLE [テーブル名] QUICK; を 実行するという事でいいのでしょうか?

    • ベストアンサー
    • MySQL
  • ビューにインデックスを設定できませんか?

    SQL Server 2005 EXPRESS を使用しています。 トランザクションのテーブルにマスタを結合して表示するビューを作成しました。 実際に利用する時はトランザクションテーブルの主キーを検索に多用すると予想されるので、該当のフィールドにインデックスを設定したいのですが… Management Studio でインデックスを設定しようとするとエラーになります。 エラーメッセージは インデックス '' の作成に失敗しました。 (Microsoft.SqlServer.Express.Smo) ------------------------------ ADDITIONAL INFORMATION: Transact-SQL ステートメントまたはバッチの実行中に例外が発生しました。 (Microsoft.SqlServer.Express.ConnectionInfo) ------------------------------ ビュー 'View' に インデックス を作成できません。ビューにはスキーマがバインドされていません。 (Microsoft SQL Server, Error: 1939) となっています。まさにメッセージのとおりだとは思うのですが 「ビューにスキーマをバインドする」方法がわかりません。 どなたかご教授いただければ助かります。 よろしくお願いいたします。