ハードディスクメンテナンス

当サイトには広告が含まれています。

タグ:遅い



3コアのCPUに換装したDBサーバーであるが、重いクエリを発行した場合、複数コアを有効に使っていないことに気付く。

まぁ、これは換装前(2コア)の時点で、既に分かっていたことであるが。

# 今回は余っていたCPUを転用しただけで、費用は掛かっていないのだ。

実際にモニターしてみると...

3コア

グラフの全範囲でCPU占有率は高いものの、100%に達しているのは3つあるうちの1コアだけである。

しかも、ほとんどが橙色(CPU1)であり、たまに赤色(CPU2)と緑色(CPU3)が「登板」するものの、それらはごく短時間。

CPU1がMAX(100%)まで使われている間、CPU2とCPU3が40%以下で休んでいるなら、CPU2とCPU3もMAXまで使い、処理時間を短くしろ、と、普通は考えるだろう。

同じハード構成で、別のパターン。

3コア

CPUの入れ替わりは先の場合に比べ頻繁になってはいるが、100%に達しているのは1つだけだ。

ッたく、他は何をやってるんだ!

これなら3コアを雇用する意味はない!

解雇(クビ)だ!クビ!

と、実世界ではなりそう(マジレスするとなってるw)が、これは、1つのクエリを複数のコアで処理することができないため。

また、本件のMySQLのバージョンは5.1.73であり、古いことも影響している。

まぁ、最近はシングルコアを探すのが難しく、最安のCeleronでもDualコアなので、あまり神経質になることもなかろう。

複数クエリや複数使用となってくると、複数コアのメリットが生きてくる。

今回は業務(つまり社内)用途であり、同時利用者数がそれほど多くないので、複数コアを上手く生かせないが、これが一般公開WEBサービス等で、利用者が非常に多い場合は、複数コアを生かせるだろう。

サーバーの場合、ディスクやメモリーは分かりやすい(簡単)であるが、CPUの場合は意外と複雑なのだ。

クライアント端末の場合は、CPU不可が高い原因は比較的簡単に掴めるし、用途が分かればCPU能力が必要かは判断できる(エンコードであればCPU等)が、サーバーの場合は用途だけでなく、その細部を探らなければならない。

いずれにしても今は安いので、それなりの用途(大規模ではない)であれば、CPUもメモリーもディスクもそれなりのもので十分。

それでも遅いなら、DBの設計やSQL文、indexが有効に使用されているか等を見直すことだ。

あとは、工夫。

最終結果の表示が遅いなら、最終結果をDBに格納しておき、それを出せば軽くなる。

少しでも速く ━

開発をしているとそういう気になってしまい、CPUを変えたら?と思うが、そういう場合、替えても大して速くならない(泣)

その後、基本に戻るのだが、そのような考えが「定期的に」出てくるので困ったものだ(笑)

実践ハイパフォーマンスMySQL 第3版
Baron Schwartz Peter Zaitsev Vadim Tkachenko
オライリージャパン
売り上げランキング: 21,426

[PR] au PAY / au WALLET カード 情報

このエントリーをはてなブックマークに追加 mixiチェック



遅杉流、危険杉流、ReadyNAS 104





「あと559時間」と表示された段階で普通はキレるだろうが、気長に待ってみる作戦wwwww





すると...





ReadyNAS 104,RN10400-100AJS,コピー,遅い





残り時間:0:00





残り時間算出を諦めたようですwwwwwwwwww





ありがとうございましたwwwwwwwwwwwwwwwwwwww

NETGEAR Inc. ReadyNAS 104 【3年保証】 4ベイ Diskless RN10400-100AJS
ネットギア (2013-05-31)
売り上げランキング: 1,853

[PR] au PAY / au WALLET カード 情報

このエントリーをはてなブックマークに追加 mixiチェック



遅杉ReadyNAS 104(RN10400-100AJS)の件。

コピー開始後、しばらくは20MB/sくらい出ているのだが、ドンドン速度が低下し、そのまま放置すると、

ReadyNAS 104,RN10400-100AJS,コピー,遅い

ReadyNAS 104,RN10400-100AJS,コピー,遅い

残り時間:559時間wwwww

0.4MB/swwwwwwwwww

で、経時とともに速度は低下していくので、時間が経つにつれ残り時間が増加する罠wwwwwwwwwwwwwwwwwwww

このNAS、危険杉流wwwwwwwwww

NETGEAR Inc. ReadyNAS 104 【3年保証】 4ベイ Diskless RN10400-100AJS
ネットギア (2013-05-31)
売り上げランキング: 1,853

[PR] au PAY / au WALLET カード 情報

このエントリーをはてなブックマークに追加 mixiチェック



あるファイルサーバー(Atom機)からNETGEARのNASであるReadyNAS 104(RN10400-100AJS)にファイル群(500GB程度)をコピーすると徐々に速度が落ち0.3MB/sとかなり終了まで250時間とかフザけたことになると書いたが、

そのAtom機から、別のWindowsマシンに接続したハードディスク(USB2.0接続)に同じファイル群をコピーすると、約1日で終了する罠。

これはつまり、ReadyNAS 104(RN10400-100AJS)が●ソということになるのか?

[PR] au PAY / au WALLET カード 情報

このエントリーをはてなブックマークに追加 mixiチェック



新記事[MySQL] 日付比較や日付検索が遅いのでBETWEENで改善させる

datetime型の列(reg_time)があるテーブルに対し、年月日指定をかけてデータを取り出す。

注:datetime型の例:2014-01-01 12:34:56

SELECT * FROM `テーブル名` WHERE `reg_time` LIKE '2014-01-01%'

これは非常に遅い。

reg_timeにindexを設定しても、indexが使用されないので無意味。

初心者が多用するLIKEなんか使うからだよ!ということで、dateを使うが、

注:dateはdatetime型(2014-01-01 12:34:56)から年月日(2014-01-01)を取り出す関数。

SELECT * FROM `テーブル名` WHERE date(`reg_time`) = '2014-01-01'

これも同様に遅い(indexも使用されない)。

この解決方法は、BETWEENを使用することである。

SELECT * FROM `テーブル名` WHERE `reg_time` BETWEEN '2014-01-01 00:00:00' AND '2014-01-01 23:59:59'

これにより、高速化が可能。

EXPLAINで動作を見ると、typeがallからrangeになっていることが分かる。

typeは、テーブルに対してどのような方法でアクセスするのかを示すもの。

allフルテーブルスキャンで、インデックスが全く使用されていないことを表す、最悪なモノだ。

一方rangeは、インデックスを用いた範囲検索である。

2014年1月1日の始端(00:00:00)と終端(23:59:59)を設定し、その間(BETWEEN)とすれば、同じものがSELECTでき、強引にBETWEEN化できるのは分かる。

まぁ、これはそれでよいとして、年月指定(日がない)の場合はどうか。

月毎の集計とかね。

当然、

SELECT * FROM `テーブル名` WHERE `reg_time` LIKE '2014-01-%'

は遅く、同様に

SELECT * FROM `テーブル名` WHERE LEFT(`reg_time`,'7') = '2014-01'



SELECT * FROM `テーブル名` WHERE LEFT(`reg_time`,'8') = '2014-01-'

注:LEFT(`reg_time`,'7')は、reg_timeの左から7文字を取り出す、つまり年-月を取得する関数。

も遅い。

となると、高速化が考えられるのはBETWEENとなるが、時刻の場合は終端が23:59:59で決まるが、月日の場合の終端日はどうするか?

終端日は、月によって異なるだろう?

まぁ、ダメだと思って

SELECT * FROM `テーブル名` WHERE `reg_time` BETWEEN '2014-01-01 00:00:00' AND '2014-01-32 23:59:59'

とすると...

エラーにはならないが、返された結果が0となり、不可wwwww

32日は存在しない日だからだろう。

となると、その月の最終日(月末日,晦日)を求めなければならない。

PHPであれば、

cal_days_in_month(CAL_GREGORIAN,$month,$year)

という関数がある(年と月の順序に注意)。

これは月末を求める関数ではなく、その年月の日数($hikazu)を求めるものだ。

日数が分かるということは、最終日($last_day)は

$hikazu = cal_days_in_month(CAL_GREGORIAN,$month,$year) ;

$last_day = $year."-".sprintf("%02d",$month)."-".sprintf("%02d",$hikazu) ;

として求められるので、

$from = $year."-".sprintf("%02d",$month)."-01 00:00:00" ;

$to = $last_day." 23:59:59" ;

SELECT * FROM `テーブル名` WHERE `reg_time` BETWEEN '$from' AND '$to'

とすればよい。

また、MySQLの日付/時刻関数にlast_dayというものがある。

これは、与えた年月日の月末(年月日)を返す。

last_day('2014-01-01') → 2014-01-31

これを使うと、

$from = $year."-".sprintf("%02d",$month)."-01" ;

SELECT * FROM `テーブル名` WHERE `reg_time` BETWEEN CONCAT('$from',' 00:00:00') AND CONCAT(last_day('$from'),' 23:59:59')

とすることができる。

BETWEENを使うと高速化できるのは分かるが、コードが長くなるし、直感的でもないし、スマートじゃないね...

[PR] au PAY / au WALLET カード 情報

このエントリーをはてなブックマークに追加 mixiチェック

このページのトップヘ