Your SlideShare is downloading. ×
大規模CSVをMySQLに入れる
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

大規模CSVをMySQLに入れる

5,066

Published on

0 Comments
11 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,066
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
8
Comments
0
Likes
11
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 大規模 CSV を MySQL に入れる 飯塚修平
  • 2. この発表の目的• ログデータ数年分を MySQL (RDS) に入れる。 – 30万レコード/(日・テーブル) * 365 日/年 * 3 年 * 5 テーブル = 16 億レコードくらいの規模 – とりあえず 1 年分だけでも入れたい・・・• 今回の苦悩を紹介することで、今後同じようなタスクに 取り組む人の参考にしてもらう。• さらに良い方法があればぜひ紹介してください。
  • 3. まず• BULK INSERT で書いた – ウェブアプリで API のレスポンスを格納する時にはよく使う • Facebook の友人リストとか, 某の ID リストとか – INSERT INTO tbl VALUES (val,val,val), (val,val,val), (val ...• 遅すぎ。
  • 4. ので• LOAD DATA INFILE で書いた – はやい! – 基本的に • “” あり→ VARCHAR, TEXT • “” なし→ INT, FLOAT – しかし、上手くやれば DATETIME 型に対応したり、文字列処理 しながら入れることも可能
  • 5. たとえば• こんな CSV – “セッションID”, “Page”, “タイムスタンプ”, “Page Views” – "10000339141949907327:6","1","2011/01/01 12:10:27",1• こんな テーブル – session_id VARCHAR(100) NOT NULL – session_num INTEGER(11) NOT NULL – to_page INTEGER(11) NOT NULL – timestamp DATETIME NOT NULL – page_view INTEGER(11) NOT NULL • ちなみに、NOT NULL をつけていないカラムをキーにして走査するとパフォーマン スが落ちる。参考 http://www.mysqlperformanceblog.com/2007/04/10/count-vs- countcol/
  • 6. ならばこんなかんじLOAD DATA LOCAL INFILE „hoge.csv‟ # RDS の場合 LOCAL が必要REPLACE INTO TABLE tbl # REPLACE か IGNORECHARACTER SET utf8FIELDS TERMINATED BY „,‟ # CSV なのでOPTIONALLY ENCLOSED BY „“‟ # “”囲みなのでIGNORE 1 LINES # 先頭行は無視する(@var1, to_page, @var2, page_view)SETsession_id = SUBSTRING(@var1, 1, LOCATE(:, @var1)-1), session_num =SUBSTRING(@var1, LOCATE(:, @var1)+1),timestamp = STR_TO_DATE(@var2, %Y/%m/%d %H:%i:%s‟);“10000339141949907327:6” → “10000339141949907327”, 6DATETIME の型を指定する参考 http://kedar.nitty-witty.com/blog/load-delimited-data-csv-excel-into-mysql-server
  • 7. InnoDB か MyISAM か• とりあえず InnoDB? ◯ トランザクション対応 • ウェブサービスでは必須 ◯ 行ロック ✕ データサイズが大きい • MyISAM の 2~3 倍 ✕ 構造が複雑• MyISAMを使うことに。 ◯ SELECT COUNT(*) が異様に速い • InnoDB → type=INDEX, MyISAM → type=NULL • 参考 http://opendatabaselife.blogspot.jp/2009/10/myisaminnodb.html ✕ テーブルロック• バッチ、SELECT 中心なら MyISAM がいいかも• ウェブで使うなら InnoDB – 参考 http://nippondanji.blogspot.jp/2009/02/myisaminnodb.html
  • 8. 高速化のために• EXPLAIN をつかってチューニング – select_type → type の順にチューニング• できるだけ SUBQUERY はつかわない – SELECT ... WHERE IN (SELECT ...) みたいなやつ – 基本的に LEFT JOIN で書き換えられるはず – select_type = SINPLE を目指す • 具体的なことは・・・ http://nippondanji.blogspot.jp/2009/03/mysql_25.html• INDEX で絞る – type = ALL(フルテーブルスキャン)または type = INDEX(フルインデックススキャン)は要改善。• key_len が短くなるように – UTF-8 の場合、 “123” は 9, 123 は 3参考 http://nippondanji.blogspot.jp/2009/03/mysqlexplain.html
  • 9. RDS のインスタンスと書き込み速度 small medium
  • 10. まとめ• 基本的に InnoDB。しかし、書き込みをしない、全文検 索したいなど、特別な状況では MyISAM を検討しても よい。• LOAD DATA INFILE 構文のオプションを使いこなせば、 大抵のことはできる。• 無駄なく適切なデータ型でスキームを書くべし。• 高速化のためには EXPLAIN でチューニングを行うべ し。

×