teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

5

誤った内容の修正

2016/08/05 09:28

投稿

hirohiro
hirohiro

スコア2068

answer CHANGED
@@ -12,11 +12,13 @@
12
12
  しかしこのような場合は、まず販売済みの古いデータを定期的にバックアップに移して省くことを検討したほうが良いかもしれません。あまりにレコードが多いとデータ登録時のindex作成も負担になってくるためです。(データ件数が膨大ということは登録や更新も頻繁に行われるということですし)
13
13
 
14
14
  **追記**
15
+ ところで上記のような例でpriceにもindexがあり、全体に対する「price > 1000」が「st = 2」よりも少ないと簡単に予測できる場合、オプティマイザは「price > 1000」を先に実行するプランを選択するかも知れません。そうすると「st = 2」のために極少数のレコードのソートで済みstへのindexにあるなしに関わらず実行速度が殆ど変わらなかった。ということもあるかも知れません。
16
+
17
+ ---
18
+ **以下の部分はコメントで指摘いただいた通り誤りで、極端に分布が偏った方を参照するのでない限りindexに意味は無いようです。**
15
19
  > カーディナリティが低くても、対象テーブルのレコードの分布に偏りがある場合は
16
20
 
17
21
  仮に偏りが無くても、また100:100万に対して100万の方を選択する絞込みだったとしても、ソートが必要になる時点でindexには意味が出てくるように思います。
18
22
  そして絞込みや検索には大抵ソートが必要です。(たぶん)
19
23
  カーディナリティが高い例えばユニークidのような要素だと、indexはその要素を条件にした結合などの操作にも威力を発揮します。しかしカーディナリティが低い要素では境界を発見するような操作にしか威力を発揮できないので、コストが同じな割りに用途が少なく効率が悪いということだと思います。
20
24
  でも”その操作をこそメインに頻繁に行う”のであれば意味はあるんじゃないかな。。
21
-
22
- ところで上記のような例でpriceにもindexがあり、全体に対する「price > 1000」が「st = 2」よりも少ないと簡単に予測できる場合、オプティマイザは「price > 1000」を先に実行するプランを選択するかも知れません。そうすると「st = 2」のために極少数のレコードのソートで済みstへのindexにあるなしに関わらず実行速度が殆ど変わらなかった。ということもあるかも知れません。

4

修正

2016/08/05 09:28

投稿

hirohiro
hirohiro

スコア2068

answer CHANGED
@@ -19,4 +19,4 @@
19
19
  カーディナリティが高い例えばユニークidのような要素だと、indexはその要素を条件にした結合などの操作にも威力を発揮します。しかしカーディナリティが低い要素では境界を発見するような操作にしか威力を発揮できないので、コストが同じな割りに用途が少なく効率が悪いということだと思います。
20
20
  でも”その操作をこそメインに頻繁に行う”のであれば意味はあるんじゃないかな。。
21
21
 
22
- indexはその要素専用のソート済みテーブルを作成して同時更新してい状態で、追加や更新の都度ソートされます。だか検索よりも更新のほう頻繁に発生するテーブルや、殆ど検索に利用されない要素に作成する返ってシステムを遅くし
22
+ ところで上記のような例でpriceにもindexがあり、全体に対する「price > 1000」が「st = 2」よりも少ないと簡単に予測できる場合、オプティマイザ「price > 1000」を先に実行するプランを選択するかも知れません。うすると「st = 2」ために極少数レコードのソート済みstへのindexなしに関わず実行速度が殆ど変わらかった。とうこもあるかも知れせん

3

追記

2016/08/04 14:36

投稿

hirohiro
hirohiro

スコア2068

answer CHANGED
@@ -9,4 +9,14 @@
9
9
  「未販売」と「販売済み」を選り分ける作業がindexによってほぼ無くなる程度まで軽減されるので、この作業のコストが高ければ高いほど(つまりレコード件数が多いほど)効果があります。
10
10
  そして(上記の設定のように)その選り分ける作業こそがそのSQLのコストの大半だったなら、高速化率も高くなります。
11
11
 
12
- しかしこのような場合は、まず販売済みの古いデータを定期的にバックアップに移して省くことを検討したほうが良いかもしれません。あまりにレコードが多いとデータ登録時のindex作成も負担になってくるためです。(データ件数が膨大ということは登録や更新も頻繁に行われるということですし)
12
+ しかしこのような場合は、まず販売済みの古いデータを定期的にバックアップに移して省くことを検討したほうが良いかもしれません。あまりにレコードが多いとデータ登録時のindex作成も負担になってくるためです。(データ件数が膨大ということは登録や更新も頻繁に行われるということですし)
13
+
14
+ **追記**
15
+ > カーディナリティが低くても、対象テーブルのレコードの分布に偏りがある場合は
16
+
17
+ 仮に偏りが無くても、また100:100万に対して100万の方を選択する絞込みだったとしても、ソートが必要になる時点でindexには意味が出てくるように思います。
18
+ そして絞込みや検索には大抵ソートが必要です。(たぶん)
19
+ カーディナリティが高い例えばユニークidのような要素だと、indexはその要素を条件にした結合などの操作にも威力を発揮します。しかしカーディナリティが低い要素では境界を発見するような操作にしか威力を発揮できないので、コストが同じな割りに用途が少なく効率が悪いということだと思います。
20
+ でも”その操作をこそメインに頻繁に行う”のであれば意味はあるんじゃないかな。。
21
+
22
+ indexはその要素専用のソート済みテーブルを作成して同時に更新している状態で、追加や更新の都度ソートされます。だから検索よりも更新のほうが頻繁に発生するテーブルや、殆ど検索に利用されない要素に作成すると返ってシステムを遅くします。

2

サンプル修正

2016/08/04 14:02

投稿

hirohiro
hirohiro

スコア2068

answer CHANGED
@@ -2,15 +2,11 @@
2
2
  ```sql
3
3
  SELECT *
4
4
  FROM item
5
- INNER JOIN (
6
- SELECT *
7
- FROM item_st
8
- WHERE f = 2
9
- ) st ON item.id = st.id
5
+ WHERE st = 2 /* 未販売 */
10
- WHERE item.price > 1000
6
+ AND price > 1000
11
7
  ```
12
- このようなSQL発行が多く、未販売が100件程度で販売済みが数百万件のような場合、item_stのf(未販売or販売済み)にindexがあればSQLの実行自体は高速化されるでしょう。
8
+ このようなSQL発行が多く、未販売が100件程度で販売済みが数百万件のような場合、st(未販売or販売済み)にindexがあればSQLの実行自体は高速化されるでしょう。
13
9
  「未販売」と「販売済み」を選り分ける作業がindexによってほぼ無くなる程度まで軽減されるので、この作業のコストが高ければ高いほど(つまりレコード件数が多いほど)効果があります。
14
- そして(上記の設定のように)その選り分ける作業こそがSQLのコストの大半だったなら、高速化率も高くなります。
10
+ そして(上記の設定のように)その選り分ける作業こそがそのSQLのコストの大半だったなら、高速化率も高くなります。
15
11
 
16
12
  しかしこのような場合は、まず販売済みの古いデータを定期的にバックアップに移して省くことを検討したほうが良いかもしれません。あまりにレコードが多いとデータ登録時のindex作成も負担になってくるためです。(データ件数が膨大ということは登録や更新も頻繁に行われるということですし)

1

コード修正

2016/08/04 13:30

投稿

hirohiro
hirohiro

スコア2068

answer CHANGED
@@ -5,11 +5,11 @@
5
5
  INNER JOIN (
6
6
  SELECT *
7
7
  FROM item_st
8
- WHERE f = '未販売'
8
+ WHERE f = 2
9
9
  ) st ON item.id = st.id
10
10
  WHERE item.price > 1000
11
11
  ```
12
- このようなSQL発行が多く、未販売が100件程度で販売済みが数百万件のような場合、item.stにindexがあればSQLの実行自体は高速化されるでしょう。
12
+ このようなSQL発行が多く、未販売が100件程度で販売済みが数百万件のような場合、item_stのf(未販売or販売済み)にindexがあればSQLの実行自体は高速化されるでしょう。
13
13
  「未販売」と「販売済み」を選り分ける作業がindexによってほぼ無くなる程度まで軽減されるので、この作業のコストが高ければ高いほど(つまりレコード件数が多いほど)効果があります。
14
14
  そして(上記の設定のように)その選り分ける作業こそがSQLのコストの大半だったなら、高速化率も高くなります。
15
15