ミュートス・ラボ Mythos-labo
temporary table を試してみる(前篇:SQLの速度アップ)
- 2009年8 月18日(火)
- 未分類
こんにちは、tatsumi です。
やっと関西地方も遅い梅雨明けを迎えました。
暑さが厳しくなっておりますが、みなさまはいかがお過ごしでしょうか。
私はといえば、毎年恒例の富士登山へ行ってまいりました。
天気予報によると「曇り一時雨か雷雨」という状態でしたが、
5合目まで行ったら綺麗な空!
「なんだかー、行けそうな気がするー!!」ということで決行したものの、
頂上へ辿り着く直前に雨が降ってきてご来光が全く見れず。
山頂は暴風雨で身の危険を感じ、さっさと下山してきました。
「自然は壮大で美しい。だけれども、厳しい」
そんなことを改めて認識した夏でした。
ところで、今日は MySQL のTEMPORARY TABLEについて書いてみようと思います。
TEMPORARY TABLE とはずばり一時テーブルのことで、マニュアルによると
テーブルを作成する時、TEMPORARY キーワードを利用する事ができます。TEMPORARY テーブルは現在の接続でのみ現れ、接続が終了すると自動的にドロップされます。これは、2つの異なる接続同士、または、既存の同名の非TEMPORARY テーブルとお互いに対立する事無く、同じテンポラリ テーブル名を利用する事ができるという意味になります。(テンポラリ テーブルがドロップされるまで、既存テーブルは隠されています。)テンポラリ テーブルを作成する為には CREATE TEMPORARY TABLES 特権を持つ必要があります。
というもの。
作り方は簡単で、普通の CREATE TABLE 文に TEMPORARY キーワードをつけて
CREATE TEPMPORARY TABLE とするだけです。
「で?」と思われる方もいらっしゃいますが、
この TEMPORARY TABLE を上手く使うと色々なメリットがあります。
そのメリットとはざっくり2つ。
「SQLの速度アップ」と「ロックの回避」です。
今回は、SQLの速度アップについてご説明します。
複雑な集計などを行う際に、サブクエリを使うことがあると思います。
例えば、
select user.user_id, sammary_1.value, sammary_2.value, sammary_3.value from user -- 1列目に出したい集計値 left join ( [サブクエリ] ) as summary_1 on user.user_id = summary_1.user_id -- 2列目に出したい集計値 left join ( [サブクエリ] ) as summary_2 on user.user_id = summary_2.user_id -- 3列目に出したい集計値 left join ( [サブクエリ] ) as summary_3 on user.user_id = summary_3.user_id
といったような場合です。
このとき、全体のデータ量が少なければ大した問題にならないのですが、
ちょっとデータ量が多くなると急に遅くなります。
理由はEXPLAIN を実行すると一目瞭然ですが、
サブクエリの結果を結合する際に「条件のFULLスキャン」が発生するためです。
ここで TEMPORARY TABLE を使用します。
-- 1列目に出したい集計値 create temporary table summary_1( PRIMARY KEY(user_id) ) [サブクエリ]; -- 2列目に出したい集計値 create temporary table summary_2( PRIMARY KEY(user_id) ) [サブクエリ]; -- 3列目に出したい集計値 create temporary table summary_3( PRIMARY KEY(user_id) ) [サブクエリ]; -- 集計結果をまとめて表示する select user.user_id, sammary_1.value, sammary_2.value, sammary_3.value from user left join summary_1 on user.user_id = summary_1.user_id left join summary_2 on user.user_id = summary_2.user_id left join summary_3 on user.user_id = summary_3.user_id
実は TEMPORARY TABLE にも PRIMARY KEY などのインデックスを設定することが可能なので
上記のようにすれば、結合時にインデックスが使用されることになり
データ量が増えても比較的高速に検索することが可能になります。
もちろん、新規にテーブルを作成するコストやインデックスを作成するコストが新たに発生するので
上記のように書けば速くなるとは一概には言えません。
しかし、どうにも速度が出ないと悩んでいるのであれば試してみる価値があると思われます。
いかがだったでしょうか。
サブクエリを TEMPORARY TABLE に抜き出して
PRIMARY KEY を設定し、結合にインデックスを使用できるようにする。
あまり使用する頻度は高くないと思いますが、
こんなことができるというご紹介でした。
次回は TEMPORARY TABLE を使用して「ロックを回避する」ことについて書きます。
TCPDFを使ってみる
- 2009年7 月13日(月)
- 未分類
UTF-8が使えるPHPのPDFライブラリを探していた時に
TCPDFというのがあると知り、色々と調べていたところ
「フォント埋め込みされることが原因で、ファイルサイズが大きくなってしまう」
というコメントがたくさん見つかりました。
そこで、マニュアルを読んだところ
フォント埋め込みをせずにPDF出力する方法があると分かったので
ちょこっとご紹介。
1.ダウンロード
TCPDFの本家サイトから最新のソースをダウンロードする
http://www.tecnick.com/public/code/cp_dpage.php?aiocp_dp=tcpdf
2.フォント設定
デフォルトでは日本語が使えないようなので、今回はMS明朝を使えるようにしてみます。
①ms-mincho.ufmファイルを生成する
C:\WINDOWS\Fonts にある MSMINCHO.TTF を ms-mincho.ttf にリネームして、
TCPDFのルートディレクトリ配下にある [TCPDF_ROOT]\fonts\utils に配置して、下記コマンドを実行します。
[コマンドプロンプト]
> cd [TCPDF_ROOT]\fonts\utils
>ttf2ufm.exe -a -F ms-mincho.ttf
②ms-mincho.phpファイルを生成する
ms-mincho.ttf ファイルと ms-mincho.ufm ファイルから ms-mincho.php ファイルを生成します。
[コマンドプロンプト]
>php -q makefont.php ms-mincho.ttf ms-mincho.ufm 0
※ここでmakefont.php の第3引数に 0 をセットすると、
PDFファイルにフォント埋め込みを行わなくなります。
何も指定しない場合は、フォント埋め込みが行われファイルサイズは大きくなります。
③ms-mincho.phpファイルを編集する
先ほど作成した ms-mincho.php ファイルを編集します。
[テキストエディタ]
//フォントタイプを変更する。
$type=’cidfont0′;
//デフォルトのフォント幅を設定する。
$dw=1000;
$name=’MS-Mincho’;
$desc=array(’Ascent’=>859,’Descent’=>-141,’CapHeight’=>27,
‘Flags’=>32,’FontBBox’=>’[-82 -137 996 859]‘,
‘ItalicAngle’=>0,’StemV’=>70,’MissingWidth’=>600);
$up=-94;
$ut=47;
$cw=array(【長すぎるので省略】);
$diff=”;
//不要なので削除する
//$enc=”;
//$ctg=”;
//$file=”;
//下記を追加する
$enc=’UniJIS-UTF16-H’; //UniJIS-UTF16-V にしたら縦書きフォントになる
$cidinfo=array(’Registry’=>’Adobe’, ‘Ordering’=>’Japan1′,’Supplement’=>5);
include(dirname(__FILE__).’/uni2cid_aj16.php’);
④ms-mincho.phpファイルを移動する
[コマンドプロンプト]
>move ms-mincho.php ..\
⑤ms-mincho.phpファイルをコピーする
移動したファイルをボールド・イタリック・ボールドイタリック用にコピーして別名で保存する。
[コマンドプロンプト]
> cd [TCPDF_ROOT]\fonts
>copy ms-mincho.php ms-minchob.php
> copy ms-mincho.php ms-minchoi.php
> copy ms-mincho.php ms-minchobi.php
3.使ってみる
[テキストエディタ]
//TCPDFクラスを読み込む
require_once(‘TCPDF.php’);
//TCPDFインスタンス化
$pdf = new TCPDF(’L');
//ページ追加
$pdf->AddPage();
//フォント指定&描画
$pdf->SetFont(’ms-mincho’, ”, 16);
$pdf->SetXY(15, 20);
$pdf->Cell(100, 10, ‘TCPDF設定完了!’, 0, 0);
//出力
$pdf->Output();
これでファイルサイズがぐぐんと小さくなりましたね。
TCPDFはかなりのペースでリリースが行われているので
どんどん良いものになっていっています。要チェックですね。
javascriptのprototypeプロパティでハマった
- 2009年3 月31日(火)
- 未分類
どうも。shimazakiです。
javascriptでprototypeプロパティについてアレコレしていたら自分が大きく誤解をしていたことを理解しましたので、ついでに紹介したいと思います
以下の結果がどうなるか、って分かりますか?
Hoge.prototype = {
aList:["123"]
,xList:["456"]
};
foo = new Hoge();
foo.aList = ["789"];
foo.xList.push("789");
alert(foo.aList);//789
alert(foo.xList);//456,789
bar = new Hoge();
alert(bar.aList);//???
alert(bar.xList);//???
正解はbar.aListは「123」 bar.bListは「456,789」と表示されます。
何を勘違いしていたか?
JavaScriptでオブジェクト指向
- 2009年3 月31日(火)
- JavaScripts/Ajax
shimazakiです。
先日社内でJavaScriptでオブジェクト指向、という発表をおこないましたので、その資料を公開します。
JavaScriptを本格的に勉強し始めて約半年ほどになりますが、とりあえずの一段落がついたかな、という感じがします。
DOM入門
- 2009年2 月26日(木)
- JavaScripts/Ajax
shimazakiです。
先日社内で勉強会をした際にDOM入門、という名目で発表をおこないましたので、その資料を公開します。
DOMは「element」という概念と、ドキュメントツリーと、ブラウザごとの差異が理解できれば後は理解への妨げになるものは無いかなと思います。