Home

ミュートス・ラボ Mythos-labo

投稿タイトル temporary table を試してみる(前篇:SQLの速度アップ)

こんにちは、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を使ってみる

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.JPG

これでファイルサイズがぐぐんと小さくなりましたね。

TCPDFはかなりのペースでリリースが行われているので
どんどん良いものになっていっています。要チェックですね。



投稿タイトル javascriptのprototypeプロパティでハマった

どうも。shimazakiです。

javascriptでprototypeプロパティについてアレコレしていたら自分が大きく誤解をしていたことを理解しましたので、ついでに紹介したいと思います

以下の結果がどうなるか、って分かりますか?

    JAVASCRIPT:
    function Hoge(){}
    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でオブジェクト指向

shimazakiです。

先日社内でJavaScriptでオブジェクト指向、という発表をおこないましたので、その資料を公開します。

JavaScriptを本格的に勉強し始めて約半年ほどになりますが、とりあえずの一段落がついたかな、という感じがします。



投稿タイトル DOM入門

shimazakiです。

先日社内で勉強会をした際にDOM入門、という名目で発表をおこないましたので、その資料を公開します。

DOMは「element」という概念と、ドキュメントツリーと、ブラウザごとの差異が理解できれば後は理解への妨げになるものは無いかなと思います。



Home

ページ
メタ情報

Page Top