アラのアラアラしい日記

こっそりかいてます

MySQLでサブクエリする時は一度LAST_INSERT_ID()を思い出してみると幸せになるかもしれない

すごく長いタイトルになりました(゜∀。)
MySQLネタです。


先月から3万件くらいのデータを一気にINSERTすることが多く、
いかにして速度を上げるかというのをやっていて、
この1ヶ月で5時間から20分にまで短縮に成功したのですが、


それで、実は一番速度が上がったのが、MySQLでよく知られている関数の
LAST_INSERT_ID()を使った時でした。


MySQL :: MySQL 5.1 リファレンスマニュアル (オンラインヘルプ) :: 7.11.3 情報関数
LAST_INSERT_ID()の説明はここに書いてあります。


それまでは、

mysql> insert into foods
> (country, genre)
> values
> ('japan', 'grain');

mysql> insert into okome
> (food_id, okomegroup)
> values
> ((select id from foods where country='japan' and genre='grain'), 'hakumai')

こんな感じで、サブクエリを使って入れた値のidを他のテーブルに入れていたのですが、

実はこれだとokomeテーブルに入れる時に毎回foodsテーブルをフルスキャンしてしまって、
大量のデータを入れる時にはとても時間がかかります。

そこで、現れるのがlast_insert_id()ちゃんです。

mysql> insert into foods
> (country, genre)
> values
> ('japan', 'grain');

mysql> insert into okome
> (food_id, okomegroup)
> values
> ((select last_insert_id()), 'hakumai')

あらまシンプル!
しかも処理速度も3分の1くらいになります。
しかもtransactionの中でも使うことが出来ます。


「でも、insertしてる間に他のバッチとかでsql動いたら
違うレコードから値を持ってきちゃうんじゃないの?」

と思う人がいると思いますが、実はlast_insert_id()は
同一コネクション内で使われるので、他で動いているクエリからは影響を受けません。
ここが結構ステキポイント。


ちなみに、last_insert_id()はauto_incrementが自動生成された時のみで動くので、
insert文の中でauto_increment値を設定していた時はlast_insert_id()には何も入りません。



おしまい!

promptでコマンド実行毎に終了ステータスを表示する

今回もbash promptの話です。

先日のprompt設定に付け加えて、
実行する度に成功失敗を取得して結果を表示するようにしました。

とても簡単に出来ます。


gist5f99d08f17cb3f67039d

↑これだけです。

ちなみに、使っている絵文字はdebian系で文字化けせずに表示出来るようです。


http://i.gyazo.com/7ebadc0fd1b8904b63641024094a434b.png
↑こんな感じになりました。かわいいです。



今日はメンテナンスなので休日出社です(白目)

bashのプロンプトでgit branchとstateを表示させる

すごく寝不足なので一瞬で書きます。

oh-my-zshのthemeが素敵だなーと思っていたら、

Git branch and dirty state in Bash prompt.
↑これを見つけたので、


↑書きました。



http://i.gyazo.com/572a24e0c982552c3299cd8287beec3e.png
↑こんな感じになりました。


http://i.gyazo.com/596e2863357a7eeeff95e986933d9c3a.png
↑編集すると、こんな感じでアスターつきます。



ただdirty stateの判定部分は正規表現とかにする必要がありそうです。
寝ます。

ところでbashのtest commandってどうなってるの

最近shellの話が多いですが今回もshellです。

ちょっと前にチームのテクニカルリーダーから教えてもらった話に
感動したので忘備録として書きます。


f:id:wknar0311:20140513194924p:plain
貝を描きましたがうまくできませんでした。


みんな大好きシェルスクリプトでは、
testコマンドを使うことが多いと思います。

例えばファイルの存在をチェックする時は、

if test -e okome.txt; then
  echo 'okome aruyo'
fi

こんなふうに書けると思います。

ただ、こっち(↓)の方がわりと主流ですよね。

if [ -e okome.txt ]; then
  echo 'okome aruyo'
fi


そして、ここで使われている" [ "って、
実はちゃんと内部コマンド(組み込みコマンド)として存在しているんです。


test commandを探してみます。

http://i.gyazo.com/922bb1f88bbadff068f251f05bd400dc.png
/usr/binの中に存在しています。

ということは、" [ " commandも、
http://i.gyazo.com/86e8626b721d1c7c8fa70557a2457ead.png
存在しちゃいます。


http://i.gyazo.com/0fc471c610bbf3333c017d703f6f97bf.png
こんな感じで、test commandと同じように使える理由が分かりますね!


ただし、[ commandの方にはルールもあります。
例えば、" ] "をなしで実行すると、

http://i.gyazo.com/43942887b5a0db80a30165b3edac5562.png
怒られます。最終引数として、" ] "が必要になります。

また、

http://i.gyazo.com/4f354ae3e70b2e525ba81fd07c308ad6.png
当たり前かもしれませんが、コマンドなのでスペースないと怒ります。



また、この [ command を実行できないOSもあるようなので注意です。


おしまい。

oh my zshをinstallしてハラショーな気分になってみる

ハラショー!!

ついに足を踏み入れてしまったので、
泣きながらoh my zshubuntuへのインストール方法書きます。
一瞬で読み終わります。

まずはzshをインストールします。

$ sudo apt-get install zsh


ただ、ubuntuの場合、zshインストールだけだとCtrlPが使えなかったり、
おかしな動きをすることが多いです。
あと、自動でzshの設定ファイルを作ってくれません。

なのでoh my zshをインストールして、command lineを見やすくするとともに、
設定ファイルもちょろっと作ってもらっちゃいます。

$ sudo apt-get install git-core
$ wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh


oh-my-zsh/tools/install.sh at master · robbyrussell/oh-my-zsh · GitHub
ここがgithubページです。


こうすると、
http://i.gyazo.com/286e12790abe9f9c6d9b369c255d8eb4.png
いきなりファンシーなpromptになります。(何度かEnter押してます。)
home直下に.zshrcも出来ています。


他にもたくさんのファンシーなテーマがあります。
Themes · robbyrussell/oh-my-zsh Wiki · GitHub


ここから好きな名前を選んで、
.zshrcを編集します。


中に、

ZSH_THEME="robbyrussell"

という行があるので、ここの"robbyrussell"を変えます。


私は"ys"というテーマを入れました。
http://i.gyazo.com/85e6c560669a45ce0a8090a75af875af.png
ナイスファンシーです。gitのbranchとかstatusも表示してくれちゃってます。

~/.oh-my-zsh/themesに一覧が入っているので、
編集したり追加してみるのもアリっすね。

zshが気に入った人はzshをデフォルトにしちゃってもいいですね。

% chsh -s `which zsh`


おしまい。

みんな大好きsedコマンドでそのままファイルを編集しちゃうよ

こんにちは。

みんなが大好きな「sedawk」のsedの話です。

sedといえば、文字列の置換とかが出来るコマンドですが、
例えば、5万行あるokome.txtというファイルをテストだけに
使いたいので1万行にしたい!とかなった時に、

以下のように出来ます。

$ sed -e '10001, $d' okome.txt > genmai.txt

↑「$」は最終行という意味です。

これでgenmai.txtをwc -lとかすると1万行になります。

が、ファイルいちいち出力しなくてもいい!編集しちゃおうぜ!
って方は、iオプションでそのまま上書きできちゃいます。

$ sed -i '10001, $d' okome.txt

ちなみに-iは--in-placeの略です。

おしまい!

bashとzshで連番とかやりたい時って何が違うの?

私のいるチームではzshを使っている人が圧倒的に多く、
bash使ってますっていうと圧倒的に萎えられたり、
定期的に無言でoh my zsh themesのリンクをチャットで送られたりするのですが、
今回はわりと使う機会が多い連番で数字を表示したい時とか、
アルファベットを順番に表示したい時の話です。

ちなみに、zshの方は使いこなせてなさすぎてviewにいらっとする人がいたらごめんなさい(アヘ顔)


結構聞くのが、連番を表示させたい時の違いで、

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
% echo {1..10}
1 2 3 4 5 6 7 8 9 10

bashzshもこれは出来るのですが、

$ echo {01..10}

bashはこれが出来ないと聞きます。

うそーんと思ってやってみました。

http://i.gyazo.com/20db91ae597a5eae1ad01782fe5fd08b.png
できました。_(:3」∠)_


できるじゃん_(:3」∠)_

どこかでアップデートされたのかな?


ちなみに、bashzshも、
http://i.gyazo.com/457d0d3562041f21044c53b58b1d501e.png
http://i.gyazo.com/986c18a0eba720bb7acc8696ba5bc729.png

こんな感じのことが出来ます。
1つ目の数字が桁数の決定になるっぽいですね。



では次にsplitとかした時に便利なアルファベットの連番(連番っていうのかな)です。

$ echo {a..z}

↑これは両方とも出来るのでしょうか!


まずは、bash
http://i.gyazo.com/9ae451930ec183b43714d0477929194c.png
できました。

つぎに、zsh
http://i.gyazo.com/06d03df75ee324a836d1d33f9fb07123.png
こちらは{a..z}という文字列がそのままechoされました。

でも、zshのオプションでブレース展開を有効にして、
「..」のところをハイフンにすると、
http://i.gyazo.com/cd511924d7e4d83c44715ad451589433.png
表示できるようになりました。

あと、zshのoptionはいっぱいあってすごいですね(小並感)
zsh: Options Index


おしまい!