回答編集履歴

1

回答を追記

2016/09/06 06:35

投稿

KiyoshiMotoki
KiyoshiMotoki

スコア4791

test CHANGED
@@ -23,3 +23,93 @@
23
23
  [https://dev.mysql.com/doc/refman/5.6/ja/index-hints.html](https://dev.mysql.com/doc/refman/5.6/ja/index-hints.html)
24
24
 
25
25
  > USE INDEX (index_list) と同様の機能を持つが、テーブルスキャンが非常に負荷が大きいと見なされる点が追加された FORCE INDEX を使用することもできます。つまり、テーブルスキャンは、指定されたインデックスのいずれかを使用してテーブル内の行を検索する方法がない場合にのみ使用されます。
26
+
27
+
28
+
29
+ # 追記
30
+
31
+
32
+
33
+ > ANALYZE TABLEやOPTIMIZE TABLEは1億レコードの場合、処理が終わらないため、
34
+
35
+ 実行しておりません。
36
+
37
+ その代り、定期的(2月に1回程度)に、別テーブルへのデータ移行&プログラム修正(参照先修正)を2日かけて行っています。
38
+
39
+
40
+
41
+ となると、相当な程度、統計情報が狂っている可能性があります。
42
+
43
+
44
+
45
+ > 更新頻度は毎秒100件くらいのDELETE / INSERTを24時間実施。
46
+
47
+
48
+
49
+ ということは 2ヶ月で約5億レコードの DELETE / INSERT が発生するため、
50
+
51
+ データ移行をする頃には、前回のデータ移行時からレコードが丸ごと入れ替わっていてもおかしくないからです。
52
+
53
+
54
+
55
+ > check table tb_test_data fast quick;
56
+
57
+ にて、テーブルの状態を確認していますが、
58
+
59
+ statusは「Table is already up to date」の状態で、問題ない認識です。
60
+
61
+
62
+
63
+ とのことですが、
64
+
65
+ 「(統計情報が)問題ない認識」
66
+
67
+ という意味なら、これは誤りです。
68
+
69
+
70
+
71
+ FAST オプションを指定すると、統計情報の更新は行なわないためです。
72
+
73
+ [https://dev.mysql.com/doc/refman/5.6/ja/check-table.html](https://dev.mysql.com/doc/refman/5.6/ja/check-table.html)
74
+
75
+ > FAST 正しく閉じられていないテーブルのみを検査します。
76
+
77
+
78
+
79
+ ---
80
+
81
+ 可能であれば、ストレージエンジンを InnoDB に変更することも検討してみてください。
82
+
83
+
84
+
85
+ InnoDB であれば統計情報は自動的に更新されます(※1)し、
86
+
87
+ ```sql
88
+
89
+ ALTER TABLE tb_test_data ENGINE InnoDB;
90
+
91
+ ```
92
+
93
+ という SQL で OPTIMIZE TABLE と同じことを、テーブルロック無しに実現できる(※2)からです。
94
+
95
+
96
+
97
+ ※1 [http://nippondanji.blogspot.jp/2010/09/innodb.html](http://nippondanji.blogspot.jp/2010/09/innodb.html)
98
+
99
+ > InnoDBの場合、ANALYZE TABLEは不要である。なぜなら、InnoDBが自発的に統計情報を更新するからだ。
100
+
101
+
102
+
103
+ ※2 同上
104
+
105
+ > InnoDBにはOPTIMIZE TABLEに相当する機能は実装されておらず、代わりにALTER TABLEが実行される。
106
+
107
+
108
+
109
+ ※2 [https://dev.mysql.com/doc/refman/5.6/ja/innodb-create-index-overview.html](https://dev.mysql.com/doc/refman/5.6/ja/innodb-create-index-overview.html)
110
+
111
+ > 並列 DML ではあるが、テーブルコピーが引き続き必要
112
+
113
+ (中略)
114
+
115
+ 「null」 ALTER TABLE ... ENGINE=INNODB ステートメントを使用したテーブルの再構築