人に聞けない痔の悩み、これでスッキリ >>

VIEWの元のテーブルのindexって有効なのでしょうか?
MYSQLサーバのバージョンは5.0.77です。
どうぞよろしくお願いします。

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

A 回答 (2件)

ビューの基表に、有効活用できるインデクスがあれば、インデクスは活用されます。



>例えば元のテーブルに「hoge_id(index)」があり、
>VIEWテーブルが「vtable」だとします。

>SELECT * FROM vtable WHERE hoge_id = 値
>または、
>SELECT * FROM vtable LEFT JOIN atable ON vatble.hoge_id = atable.id
>(atable.idもindex)

>などとした場合、hoge_idのindexが有効で高速に結果が返ってくるということでよろしいのでしょうか。

表の母体データ件数が相当に少ない(例えば、数百件など)とか、重複キー値が多量に存在するといった場合は、RDBMSのオプティマイザが、「インデクスを使うより、テーブルスキャン(表のデータを全件サーチ)した方が速い」と判断し、インデクスを利用しない場合もあります。

主キーなどユニークなキーでの「=」条件や範囲条件などで、母体データからある程度絞り込んだ検索をするなら、インデクスの活用で母体データが大量に増えても、一定の性能を出せます。
    • good
    • 1
この回答へのお礼

chukenkenkou 様、ご回答有難うございます。

なるほど、期待以上の答えを頂きました。

どうも有難うございました。

お礼日時:2010/07/24 04:11

有効です。

VIEWにはINDEXは作れませんし。
    • good
    • 0
この回答へのお礼

SaKaKashi 様、ご回答ありがとうございます。

有効なんですね。
安心しました。

えと、、
ちょっと自分の質問が説明不足だったせいで少し不安なので再確認させて頂きたいのですが、
例えば元のテーブルに「hoge_id(index)」があり、
VIEWテーブルが「vtable」だとします。

SELECT * FROM vtable WHERE hoge_id = 値
または、
SELECT * FROM vtable LEFT JOIN atable ON vatble.hoge_id = atable.id
(atable.idもindex)

などとした場合、hoge_idのindexが有効で高速に結果が返ってくるということでよろしいのでしょうか。
最初から上記のように質問すればよかったですね。。すみません。

どうぞよろしくお願いします。

お礼日時:2010/07/24 02:15

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

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

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

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

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

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

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

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

Aベストアンサー

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

QデータベースのINT型項目にNULLはNG?

以前、知り合いからデータベースのINT型の項目には出来ればNULLを許可しない(NOT NULL)方がいいと聞いたことがあるのですが、本当でしょうか?

現在不動産の物件データを登録するためのシステムを作成しており、
データベースの設計を行なっている最中なのですが、
例えば金額や面積など数字しか入力されない項目はINT型にしたいと考えています。
※データベースはMySQLになります。

ただし、
物件データ登録時に数字項目に何も入力されなければ「NULL」、
0以上の数値を入力されている場合にはそのままその数値をデータベースに登録したいと考えています。
※0を入力されている場合には「0」をそのまま入れたいです。

INT型の項目にはNULLを入れるのを避けた方がいい場合には、0を入れるような仕様に変更しようと考えているのですが、その辺のことについて教えて頂けると助かります。

ざっくりとした質問で申し訳ございませんが、宜しくお願い致します。

Aベストアンサー

物件データ登録時に数字項目に何も入力されなければ「NULL」、0を入力されている場合には「0」
本来の意図としては正しいはずです。
Nullは本来、どの値を入れればいいのかわからない値ということなので、
数字がわからない=何も入力していない ということで、Nullを指定するのは正しいはずです。
しかし、
実際に使うときには、Nullは実に不自由なので、
Nullは使うなという話がでてきます。
## 私なら、入力区分 0=未入力、1=入力 と 数値(未入力は0)と別々に持つかもしれません。

というのは例えば、
金額 100万以上の物件は何件?
というSQLに対して、100件と答えがでて、
金額 100万未満の物件は何件?
というSQLに対して、50件と答えがでたとします。
じゃあ、全物件は?・・・172件だったりします。
何故?⇒Nullが22件だったためです。
(Nullは0とは違い、どちらの検索条件にも含まれません。)
・・・この不自由さを回避するために数値項目に、Not Null制約をつけることが多いです。

Qビューにインデックスを設定できませんか?

SQL Server 2005 EXPRESS を使用しています。
トランザクションのテーブルにマスタを結合して表示するビューを作成しました。
実際に利用する時はトランザクションテーブルの主キーを検索に多用すると予想されるので、該当のフィールドにインデックスを設定したいのですが…

Management Studio でインデックスを設定しようとするとエラーになります。

エラーメッセージは

インデックス '' の作成に失敗しました。 (Microsoft.SqlServer.Express.Smo)
------------------------------
ADDITIONAL INFORMATION:
Transact-SQL ステートメントまたはバッチの実行中に例外が発生しました。 (Microsoft.SqlServer.Express.ConnectionInfo)
------------------------------
ビュー 'View' に インデックス を作成できません。ビューにはスキーマがバインドされていません。 (Microsoft SQL Server, Error: 1939)

となっています。まさにメッセージのとおりだとは思うのですが
「ビューにスキーマをバインドする」方法がわかりません。

どなたかご教授いただければ助かります。

よろしくお願いいたします。

SQL Server 2005 EXPRESS を使用しています。
トランザクションのテーブルにマスタを結合して表示するビューを作成しました。
実際に利用する時はトランザクションテーブルの主キーを検索に多用すると予想されるので、該当のフィールドにインデックスを設定したいのですが…

Management Studio でインデックスを設定しようとするとエラーになります。

エラーメッセージは

インデックス '' の作成に失敗しました。 (Microsoft.SqlServer.Express.Smo)
------------------------------
ADDITIONAL INF...続きを読む

Aベストアンサー

SCHEMABINDINGオプションがあるようですね。以下が参考になるでしょうか。
http://msdn.microsoft.com/ja-jp/library/ms187956(SQL.90).aspx
http://msdn.microsoft.com/ja-jp/library/ms173846(SQL.90).aspx

QUNION ALLでつなげた複数ビューの集計

お世話になっています。

現在下記のようなSQLを組んでいます。

ビュー1の集計結果
UNION ALL
ビュー2の集計結果
UNION ALL
ビュー3の集計結果

実行結果 例

年月     人数  金額
201104   3    20000
201105   2    10000
201104   1    5000

GROUP BY句で年月を集計したビューをUNION ALLでつないでいるため、
当然のように同じ年月が何度も出てくるため、テストがしづらくなっています。

やりたいこととしては、さっきの実行結果をさらに年月で集計することを
考えています。

年月     人数  金額
201104   4    25000
201105   2    10000


対策として、下記のように集計したビューをUNION ALLでつないだ結果を
さらに集計するSQLを作りました。

SELECT 
FROM(
ビュー1の集計結果
UNION ALL
ビュー2の集計結果
UNION ALL
ビュー3の集計結果

GROUP BY


その結果、下記のエラーが発生しました。
ORA-00935:グループ関数のネスト・レベルが深すぎます。

環境はoracle11gです。

あとは、SQLのFROM句の()の部分をビューとして作成し、
更にそのビューを呼び出して集計するくらいしか思いつかないです。

今回作ろうとしてるのはテスト用のSQLのため、SQL文と実行結果を残したいので、
できればビューやプロシージャーは作らずに、SQLのみで作成したいと考えています。

何か良い方法はありますでしょうか?

宜しくお願い致します。

お世話になっています。

現在下記のようなSQLを組んでいます。

ビュー1の集計結果
UNION ALL
ビュー2の集計結果
UNION ALL
ビュー3の集計結果

実行結果 例

年月     人数  金額
201104   3    20000
201105   2    10000
201104   1    5000

GROUP BY句で年月を集計したビューをUNION ALLでつないでいるため、
当然のように同じ年月が何度も出てくるため、テストがしづらくなっています。

やりたいこととしては、さっきの実行結果をさらに年月で集計することを
考えています。

年...続きを読む

Aベストアンサー

こういう指摘がありますけど
http://www.confrage.com/oracle/oracle_sql/tips/group_func_nest_limit/group_func_nest_limit.html

QMySQLで改行を含む文の登録のしかた(改行コード

MySQLで改行を含む文を登録したいんですが、改行を改行コードに書き換えて登録したいです。
改行コードはどのように書けばいいですか?

登録したい文:
あいうえお
かきくけこ
さしすせそ

Aベストアンサー

改行コードは¥nで登録すれば良いです。

QEXISTSを使ったDELETE文

「SELECT文の件数」と、
「同じSELECT文を使ったDELETE文の件数」が一致しない現象が起き、困っています。

【SELECT文】※2件返ってきます。
SELECT
  a.部署コード,
  a.社員コード
FROM
  社員マスタ a,
  組織マスタ b
WHERE
  a.部署コード = b.部署コード


【DELETE文】※50件 DELETEされます。
DELETE TABLE
  社員マスタ
WHERE
  EXISTS
  (
  SELECT
    a.部署コード,
    a.社員コード
  FROM
    社員マスタ a,
    組織マスタ b
  WHERE
    a.部署コード = b.部署コード
  )


環境はSQLSERVER2005です。
件数はSQLSERVER2005のカウントオプションで表示されているものなので間違いないです。

宜しくお願いします。

Aベストアンサー

EXISTS 句は、副問い合わせが行を返した場合 TRUE そうでない場合 FALSE と評価されます。

例示いただいた副問い合わせは TRUE を返すので DELETE されます。

詳細については、SQLの入門書を参考にしてください。

QMySQLのviewはデータをコピーするのですか?それともエイリアスのようなものですか?

Webページのアクセスの度に、毎回大きいテーブル同士をJOINするのは効率が悪いと思います。
そのような場合、大きいテーブル同士をJOINしたVIEWを作成しておけば、データはコピーされて速度が増すのでしょうか?
それとも、データはコピーされずに、結局、SELECTされる毎に内部的に毎回JOINされているのでしょうか?

Aベストアンサー

>100万行のテーブルのビューを作っても、ハードディスクを全く消費しない

DB格納スペースとしてはそうですが、ビュー経由で検索したときにORDER BY、GROUP BY、DISTINCTなどを行いソートが発生すれば、当然、作業用のメモリが消費されます。また、インデクスのキー以外の列を検索したり、ジョインでインデクスを有効利用できなければ、やはり作業用のメモリが消費されます。
作業用のメモリは、一時的なファイルとして、OSやRDBMSによりHDDに吐き出されることはあります。

>テーブルをJOINしたVIEWを作ったとき、そのVIEWがSELECTされる度に、毎回JOINするので、パフォーマンスアップにはならない

「ビューを経由したから」という意味では、性能改善には直結しません。
ただし、よく利用される検索パターンであったりして、DBバッファ上にデータが残っていて、結果的に実I/O減になることはあるかも知れません。
また、TEXT型やBLOB型などは、1行の情報が物理的には複数行に分割して格納されるので、ビューを経由することで、「不必要にそういった列を操作する」といった無駄は省けるかも知れません。

100万件規模のデータから、ジョインして絞り込んだ結果を、Webサービスで頻繁に利用するなら、絞り込んだ結果を実体のある表に格納しておけばどうでしょうか?
当初考えていた「ビューでジョイン」ということは、「そのビュー経由では更新しない」ということ(多くのRDBMSの制限で、MySQLも同じ)になりますから。
データの反映間隔、反映方法などの検討が必要になりますけどね。

>100万行のテーブルのビューを作っても、ハードディスクを全く消費しない

DB格納スペースとしてはそうですが、ビュー経由で検索したときにORDER BY、GROUP BY、DISTINCTなどを行いソートが発生すれば、当然、作業用のメモリが消費されます。また、インデクスのキー以外の列を検索したり、ジョインでインデクスを有効利用できなければ、やはり作業用のメモリが消費されます。
作業用のメモリは、一時的なファイルとして、OSやRDBMSによりHDDに吐き出されることはあります。

>テーブルをJOINしたVIEWを作った...続きを読む

Q主キーにインデックスは貼らないと駄目でしょうか?

いつもお世話になっております。

テーブルを作成したときに主キーのインデックスは改めて
貼る必要があるのでしょうか? それとも自動的に
インデックスを貼ってくれます?

Aベストアンサー

主キーと分かっているのならテーブル作成時にPRIMARY KEY指定していますよね?
それならばインデックスは自動で作成されるはずです。

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.区分

QSQL Server のキャラクターセット(内部文字コード)は何処で定義するのでしょうか?

SQL Server超初心者です。(Oracleについては約1年ちょっとの経験はあります)どうぞよろしくお願いします。
今回SQL Server2005 を使って簡単なシステムを構築する事になりました。
SQL Serverが扱う文字コートについて教えてください。
Oracleを使っていた時の経験としてDB内部のキャラクターセットと
クライアントで使う文字セット(NLS_LANG)を意識しておかないと、いろんな「文字化け」問題に遭遇した時に対応できませんでした。
きっとSQL Serverにおいても同じような事ではないかと思いここに質問させていただきます。
以下2点についてどなたかコメント願います。
1.(Oracleでいうキャラクターセット)はどこで定義するのでしょうか?
2.OracleでいうNLS_LANGに相当するものはあるのでしょうか?
 (ひょっとしたらマイクロソフト製品なのでサーバもクライアントもCP932固定なのでしょうか?)

根本的にはシステム構築する上で『極力文字化けに遭遇したくない』思い出このような質問をさせていただきました。
『文字化け』について注意点などありましたら合わせてコメントいただければ助かります。
以上よろしくお願いします。

SQL Server超初心者です。(Oracleについては約1年ちょっとの経験はあります)どうぞよろしくお願いします。
今回SQL Server2005 を使って簡単なシステムを構築する事になりました。
SQL Serverが扱う文字コートについて教えてください。
Oracleを使っていた時の経験としてDB内部のキャラクターセットと
クライアントで使う文字セット(NLS_LANG)を意識しておかないと、いろんな「文字化け」問題に遭遇した時に対応できませんでした。
きっとSQL Serverにおいても同じような事ではないかと思いここに質問...続きを読む

Aベストアンサー

Windowsのロケールの設定を日本語にした状態でSQLServerをインストールした場合、cp932がデフォルトの照合順序になります。照合順序については参考URLをご覧下さい。

SQLServerではわかりませんが、PostgresではJDBCドライバ部分で変換していたように記憶しています。ODBCドライバではAutoTranslateという機能があります。

このため、ODBC接続で何も考えずにvarcharを使用するとcp932になります。

参考URL:http://www.microsoft.com/japan/msdn/sqlserver/sql2005/bb330962.aspx


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング