回答編集履歴

5

誤った内容の修正

2016/08/05 09:28

投稿

hirohiro
hirohiro

スコア2068

test CHANGED
@@ -26,6 +26,14 @@
26
26
 
27
27
  **追記**
28
28
 
29
+ ところで上記のような例でpriceにもindexがあり、全体に対する「price > 1000」が「st = 2」よりも少ないと簡単に予測できる場合、オプティマイザは「price > 1000」を先に実行するプランを選択するかも知れません。そうすると「st = 2」のために極少数のレコードのソートで済みstへのindexにあるなしに関わらず実行速度が殆ど変わらなかった。ということもあるかも知れません。
30
+
31
+
32
+
33
+ ---
34
+
35
+ **以下の部分はコメントで指摘いただいた通り誤りで、極端に分布が偏った方を参照するのでない限りindexに意味は無いようです。**
36
+
29
37
  > カーディナリティが低くても、対象テーブルのレコードの分布に偏りがある場合は
30
38
 
31
39
 
@@ -39,5 +47,3 @@
39
47
  でも”その操作をこそメインに頻繁に行う”のであれば意味はあるんじゃないかな。。
40
48
 
41
49
 
42
-
43
- ところで上記のような例でpriceにもindexがあり、全体に対する「price > 1000」が「st = 2」よりも少ないと簡単に予測できる場合、オプティマイザは「price > 1000」を先に実行するプランを選択するかも知れません。そうすると「st = 2」のために極少数のレコードのソートで済みstへのindexにあるなしに関わらず実行速度が殆ど変わらなかった。ということもあるかも知れません。

4

修正

2016/08/05 09:28

投稿

hirohiro
hirohiro

スコア2068

test CHANGED
@@ -40,4 +40,4 @@
40
40
 
41
41
 
42
42
 
43
- indexはその要素専用のソート済みテーブルを作成て同時更新している状態で、追加や更新の都ソートされます。だから検索よりも更新のほう頻繁に発生するテーブルや、殆ど検索に利用されない要素に作成すと返ってシステムを遅くし
43
+ ところで上記のような例でpriceにもindexがあり、全体に対する「price > 1000」が「st = 2」よりも少ないと簡単に予測できる場合、オプティマイザ「price > 1000」を先に実行するプランを選択するかも知れません。うすると「st = 2」ために極少数レコードのソート済みstへのindexにあるなしに関わらず実行速度が殆ど変わらかった。とうこともあかも知れせん

3

追記

2016/08/04 14:36

投稿

hirohiro
hirohiro

スコア2068

test CHANGED
@@ -21,3 +21,23 @@
21
21
 
22
22
 
23
23
  しかしこのような場合は、まず販売済みの古いデータを定期的にバックアップに移して省くことを検討したほうが良いかもしれません。あまりにレコードが多いとデータ登録時のindex作成も負担になってくるためです。(データ件数が膨大ということは登録や更新も頻繁に行われるということですし)
24
+
25
+
26
+
27
+ **追記**
28
+
29
+ > カーディナリティが低くても、対象テーブルのレコードの分布に偏りがある場合は
30
+
31
+
32
+
33
+ 仮に偏りが無くても、また100:100万に対して100万の方を選択する絞込みだったとしても、ソートが必要になる時点でindexには意味が出てくるように思います。
34
+
35
+ そして絞込みや検索には大抵ソートが必要です。(たぶん)
36
+
37
+ カーディナリティが高い例えばユニークidのような要素だと、indexはその要素を条件にした結合などの操作にも威力を発揮します。しかしカーディナリティが低い要素では境界を発見するような操作にしか威力を発揮できないので、コストが同じな割りに用途が少なく効率が悪いということだと思います。
38
+
39
+ でも”その操作をこそメインに頻繁に行う”のであれば意味はあるんじゃないかな。。
40
+
41
+
42
+
43
+ indexはその要素専用のソート済みテーブルを作成して同時に更新している状態で、追加や更新の都度ソートされます。だから検索よりも更新のほうが頻繁に発生するテーブルや、殆ど検索に利用されない要素に作成すると返ってシステムを遅くします。

2

サンプル修正

2016/08/04 14:02

投稿

hirohiro
hirohiro

スコア2068

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

1

コード修正

2016/08/04 13:30

投稿

hirohiro
hirohiro

スコア2068

test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  FROM item_st
14
14
 
15
- WHERE f = '未販売'
15
+ WHERE f = 2
16
16
 
17
17
  ) st ON item.id = st.id
18
18
 
@@ -20,7 +20,7 @@
20
20
 
21
21
  ```
22
22
 
23
- このようなSQL発行が多く、未販売が100件程度で販売済みが数百万件のような場合、item.stにindexがあればSQLの実行自体は高速化されるでしょう。
23
+ このようなSQL発行が多く、未販売が100件程度で販売済みが数百万件のような場合、item_stのf(未販売or販売済み)にindexがあればSQLの実行自体は高速化されるでしょう。
24
24
 
25
25
  「未販売」と「販売済み」を選り分ける作業がindexによってほぼ無くなる程度まで軽減されるので、この作業のコストが高ければ高いほど(つまりレコード件数が多いほど)効果があります。
26
26