技術者派遣の技術日誌ブログ

June 29, 2009

Website Inspiration Blog | SpicyWebDesigners.com by Luc Arnold …

Filed under: ALL, Ajax, Javascript/Xhtml/Css — Tags: , , , — doku @ 4:07 am

Originally, I talked about SilverThemes, a company designing for the Magento Commerce platform that is producing some interesting themes and add-ons. I.

Originally, I talked about SilverThemes, a company designing for the Magento Commerce platform that is producing some interesting themes and add-ons. I.

Original post:
Website Inspiration Blog | SpicyWebDesigners.com by Luc Arnold …

June 23, 2009

Django snippets: Generic AJAX app

myProject ajax __init__.py from dispatcher import dispatcher # myProject ajax dispatcher.py from django import http import re class AlreadyRegistered(Exception): pass class NotCallable(Exception): pass class Dispatcher(object): def …

myProjectajax__init__.py from dispatcher import dispatcher # myProjectajaxdispatcher.py from django import http import re class AlreadyRegistered(Exception): pass class NotCallable(Exception): pass class Dispatcher(object): def …

See the original post here:
Django snippets: Generic AJAX app

June 21, 2009

[How To][WordPress]コメントとトラックバックを分ける方法

Filed under: Wordpress — Tags: , — strmozo @ 11:34 pm

MTユーザにはなぜこういう仕様なのか納得がいかないところですが、デフォルト状態のWordPressではコメントとトラックバックは混在して表示されるようになっています。どちらもエントリへのフィードバックという意味だからなのでしょうけど、ちょっと気持ち悪いのでこれを修正してみました。

まずは、Trackping Separator Pluginをダウンロード。英語なんて読めなくても無問題。「Step 1: Download trackpings.phps from here」のhereからダウンロードできます。

このファイルをtrackpings.phpというように名前を変更して、/wordpressインストールフォルダ/wp-content/plugins/にアップロードしてやります。

次にWordPressの管理画面にログインして、プラグインタブからTrackping Separatorを有効化します(下記画像参照)

プラグインのアクティベート

続いて、使用中のテーマのindex.php(/wordpressインストールフォルダ/wp-content/themes/テーマ名/index.php)を編集します。

<?php comments_popup_link(__('Comments (0)'), __('Comments (1)'), __('Comments (%)')); ?>という部分をエディタの検索で探して、
<?php comments_only_popup_link(__('Comments (0)'), __('Comments (1)'), __('Comments (%)')); ?> | <a href="<?php the_permalink() ?>#trackback" title="trackback/pingback" class="trackacklink">Trackback (<?php echo trackpings('count'); ?>)</a>に置き換えます。
※class=”trackbacklink”のところはテーマにあわせて適宜修正が必要かもしれません。

index.phpについてはこれで完成です。

次に個別エントリー画面の修正です。これは、Standing Tallさんにて公開されているcomments.phpを使うのが簡単でした。

wp-comments.txtをcomments.phpと名前を変えてダウンロードし、使用しているテーマのcomments.php(/wordpressインストールフォルダ/wp-content/themes/テーマ名/comments.php)に上書きしてやればOKです。

June 20, 2009

Girl Writes Code: Inconvenient Accessibility Makes Self …

Filed under: MYSQL, Oracle, PHP — Tags: , , , , , , , , — Sayuri @ 12:19 pm

NET, Oracle , and SQL Server . Oh, and PowerPoint

Read the original here:
Girl Writes Code: Inconvenient Accessibility Makes Self …

June 19, 2009

MySQLのEXPLAINを徹底解説!!

Filed under: LAMP, MYSQL — Tags: , , — doku @ 6:15 pm

MySQLのチューニングで最も大切なのは、クエリとスキーマの最適化である。スキーマの設計は一度決めてしまうとそのテーブルを利用する全てのクエリに影響してしまうためなかなか変更することは出来ないが、クエリはそのクエリだけを書き直せば良いので変更の敷居は低い。そして遅いクエリをなくすことは、性能を大幅に向上させるための最も有効な手段である。従って、アプリケーションの性能を向上させたいなら、まず最初にクエリのチューニングを検討するべきなのである。

最適化するべきクエリはスロークエリログやクエリアナライザで見付けられるが、ではそのようなクエリが見つかった場合にはどのように最適化すればいいのか?そのためにはまず現在どのようにクエリが実行されているかということを知らなくてはならない。つまり、EXPLAIN SELECT …の出力を理解することが初めの第一歩となる。クエリを最適化するということは、

  • 書き換える前と後でクエリの実行結果が同じになる
  • EXPLAINがよりよい実行計画を表示する

ということであると言える。クエリを書き換えてはEXPLAINを実行して、結果が思わしくなければまた書き換えて・・・ということ繰り返して最適化するわけである。EXPLAINの出力を理解し、どのようなクエリならMySQLが高速に実行出来るかということを知っていればこの作業は比較的簡単である。今日は前者、つまりEXPLAINの出力が何を意味するのか?ということについて解説しよう。

では以下に順を追って各フィールドの詳細を説明する。

id/select_type

MySQLのEXPLAINの見方には少々コツが要る。クエリの実行計画は内部的にはツリーで表現されているが、EXPLAINの出力は表になっているからである。つまり、EXPLAINを見ることによってツリー構造を理解しないといけないわけで、これが第一の関門となる。そのツリー構造を理解すれば、各テーブルがどのようにアクセスされるかということが容易に理解出来るだろう。

idとselect_typeはEXPLAINの最初の2つのフィールドであるが、これらはセットにして考えると良い。select_typeはクエリの種類を表すものであり、ズバリツリーの構造にそのまま反映される。クエリの種類とはJOIN、サブクエリ、UNIONおよびそれらの組み合わせで、select_typeの内容もその組み合わせから導き出されたものなのである。

JOINの場合

MySQLが実行出来るJOINの種類はNested Look Join(NLJ)の一種類しかない。NLJとは例えばA、B、Cという3つのテーブルをJOINする際、最初にテーブルAから条件にマッチする行を全てフェッチして、次にBから条件にマッチする行をフェッチしてJOINし、次にCから条件にマッチする行をフェッチしてJOINする・・・というように、テーブルを一つずつ順に処理していく方式である。MySQL 6.0ではBKA JOINというのが追加されるが、これもNLJの発展系である。(JOINの方式にはソートマージやHASH JOINなどがあるが、MySQLには実装されていない。)

クエリがJOINだけから構成される場合、select_typeはSIMPLEと表示される。如何に複雑なJOINであってもCOMPLEXとはならずにSIMPLEなのである。従って「これはシンプルなクエリを示すのだ」などと誤解をしてはならない。SIMPLEではidが全て同じ値になる。これはそのクエリが一つのNLJで処理されることを示すからである。NLJではどのテーブルから処理するのかということが最も重要になるが、EXPLAINの出力の順序がどのテーブルから処理するかということを反映している。

サブクエリの場合

サブクエリが絡むと次のselect_typeには次の5種類のうちいずれかが表示される。

  • PRIMARY・・・外部クエリを示す。
  • SUBQUERY・・・相関関係のないサブクエリ。
  • DEPENDENT SUBQUERY・・・相関関係のあるサブクエリ。
  • UNCACHEABLE SUBQUERY・・・実行する度に結果が変わる可能性のあるサブクエリ。
  • DERIVED・・・FROM句で用いられているサブクエリ。

サブクエリの場合は実行順序に気をつける必要がある。DERIVEDの場合、サブクエリ→外部クエリの順番でクエリが実行される。例えば次のような場合はCityテーブルから最初に行がフェッチされてテーブルとなり、その次にCountryテーブルとのJOINが実行される。

  1. mysql> EXPLAIN SELECT * FROM Country, (SELECT * FROM City WHERE Population > 1000000) AS C1 WHERE Country.Code = C1.CountryCode;  
  2. +—-+————-+————+——–+—————+———+———+—————-+——+————-+  
  3. | id | select_type | table      | type   | possible_keys | key     | key_len | ref            | rows | Extra       |  
  4. +—-+————-+————+——–+—————+———+———+—————-+——+————-+  
  5. |  1 | PRIMARY     | <DERIVED2> | ALL    | NULL          | NULL    | NULL    | NULL           |  237 |             |  
  6. |  1 | PRIMARY     | Country    | eq_ref | PRIMARY       | PRIMARY | 3       | C1.CountryCode |    1 |             |  
  7. |  2 | DERIVED     | City       | ALL    | NULL          | NULL    | NULL    | NULL           | 4079 | Using where |  
  8. +—-+————-+————+——–+—————+———+———+—————-+——+————-+  
  9. rows in set (0.00 sec)  
  10. </DERIVED2>  
mysql> EXPLAIN SELECT * FROM Country, (SELECT * FROM City WHERE Population > 1000000) AS C1 WHERE Country.Code = C1.CountryCode;
+----+-------------+------------+--------+---------------+---------+---------+----------------+------+-------------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref            | rows | Extra       |
+----+-------------+------------+--------+---------------+---------+---------+----------------+------+-------------+
|  1 | PRIMARY     |  | ALL    | NULL          | NULL    | NULL    | NULL           |  237 |             |
|  1 | PRIMARY     | Country    | eq_ref | PRIMARY       | PRIMARY | 3       | C1.CountryCode |    1 |             |
|  2 | DERIVED     | City       | ALL    | NULL          | NULL    | NULL    | NULL           | 4079 | Using where |
+----+-------------+------------+--------+---------------+---------+---------+----------------+------+-------------+
3 rows in set (0.00 sec)

それ以外の場合は外部クエリ→サブクエリの順番でクエリが実行される。ただしSUBQUERYの場合はサブクエリが本当に実行されるのは最初の一回だけで、それ以降はキャッシュされた実行結果が利用される。DEPENDENT SUBQUERYおよびUNCACHEABLE SUBQUERYの場合はサブクエリが行の評価の度に実行されることになる。

サブクエリの場合、外部クエリとサブクエリでは別々のidがつけられる。

UNIONの場合

クエリにUNIONが含まれる場合、次の5種類のいずれかがselect_typeに表示される。

  • PRIMARY・・・UNIONにおいて最初にフェッチされるテーブル
  • UNION・・・2番目以降にフェッチされるテーブル
  • UNION RESULT・・・UNIONの実行結果
  • DEPENDENT UNION・・・DEPENDENT SUBQUERYがUNIONになっている場合
  • UNCACHEABLE UNION・・・UNCACHEABLE SUBQUERYがUNIONになっている場合

UNIONは前から順番に処理されていくだけなので、テーブルが処理される順序という観点ではわかり易いと言えるだろう。

select_typeについては次のページにまとめてあるので参考にして欲しい。
http://www.mysqlpracticewiki.com/index.php/Select_type

table

アクセスする対象のテーブル。読んで字のごとくである。

type

select_typeの次に意識しなければいけないのは、typeフィールドである。このフィールドはレコードアクセスタイプとも呼ばれ、対象のテーブルに対してどのような方法でアクセスするかを示す。致命的なクエリはこのフィールドを見れば一目で分かるのでとても重要なフィールドである。よく見かけるものは次の通り。

  • const・・・PRIMARY KEYまたはUNIQUEインデックスのルックアップによるアクセス。最速。
  • eq_ref・・・JOINにおいてPRIARY KEYまたはUNIQUE KEYが利用される時のアクセスタイプ。constと似ているがJOINで用いられるところが違う。
  • ref・・・ユニーク(PRIMARY or UNIQUE)でないインデックスを使って等価検索(WHERE key = value)を行った時に使われるアクセスタイプ。
  • range・・・インデックスを用いた範囲検索。
  • index・・・フルインデックススキャン。インデックス全体をスキャンする必要があるのでとても遅い。
  • ALL・・・フルテーブルスキャン。インデックスがまったく利用されていないことを示す。OLTP系の処理では改善必須。

indexまたはALLを見かけたらすかさずクエリをチューニングしよう。

typeフィールドの詳細については次のページにまとめてあるので参照して欲しい。
http://www.mysqlpracticewiki.com/index.php/Record_access_types

possible_keys

オプティマイザがテーブルのアクセスに利用可能なインデックスの候補として挙げたキーの一覧。

key

オプティマイザによって選択されたキー。

key_len

選択されたキーの長さ。インデックスの走査は、キー長が短い方が高速である。インデックスをつけるカラムを選ぶ時にはそのことを念頭に置いて欲しい。

ref

検索条件で、keyと比較されている値やカラムの種類。定数が指定されている場合はconstと表示される。JOINが実行されている時には、結合する相手側のテーブルで検索条件として利用されているカラムが表示される。例えば次の例では、CountryテーブルはCityテーブルとCity.CountryCodeカラムでJOINされるということを示している。。

  1. mysql> EXPLAIN SELECT * FROM Country,City WHERE Country.Code=City.CountryCode AND Country.Name LIKE ‘A%’;  
  2. +—-+————-+———+——–+—————+———+———+————————+——+————-+  
  3. | id | select_type | table   | type   | possible_keys | key     | key_len | ref                    | rows | Extra       |  
  4. +—-+————-+———+——–+—————+———+———+————————+——+————-+  
  5. |  1 | SIMPLE      | City    | ALL    | NULL          | NULL    | NULL    | NULL                   | 4079 |             |  
  6. |  1 | SIMPLE      | Country | eq_ref | PRIMARY       | PRIMARY | 3       | world.City.CountryCode |    1 | Using where |  
  7. +—-+————-+———+——–+—————+———+———+————————+——+————-+  
  8. rows in set (0.00 sec)  
mysql> EXPLAIN SELECT * FROM Country,City WHERE Country.Code=City.CountryCode AND Country.Name LIKE 'A%';
+----+-------------+---------+--------+---------------+---------+---------+------------------------+------+-------------+
| id | select_type | table   | type   | possible_keys | key     | key_len | ref                    | rows | Extra       |
+----+-------------+---------+--------+---------------+---------+---------+------------------------+------+-------------+
|  1 | SIMPLE      | City    | ALL    | NULL          | NULL    | NULL    | NULL                   | 4079 |             |
|  1 | SIMPLE      | Country | eq_ref | PRIMARY       | PRIMARY | 3       | world.City.CountryCode |    1 | Using where |
+----+-------------+---------+--------+---------------+---------+---------+------------------------+------+-------------+
2 rows in set (0.00 sec)

rows

そのテーブルからフェッチされる行数の見積もりである。このフィールドはあくまでもテーブル全体の行数やインデックスの分散具合から導き出された大まかな見積もりなので、実際にフェッチされる正確な行数ではないので注意が必要されたい。ただし一つだけ例外がある。DERIVEDテーブルである。DERIVEDテーブルは実際に実行してみないと行数の見積もりができないので、オプティマイザはEXPLAINの際にもサブクエリを実行する。そのため、DERIVEDテーブルだけは常に正確な行数を見積もることができるわけである。ただし、DERIVEDテーブルを扱う時は、サブクエリが最適化されていない場合はEXPLAINにも時間が掛かってしまうため注意が必要だ。

また、フェッチされた全ての行がそのまま結果として返されるわけではないという点にも注意したい。後述するUsing whereがExtraフィールドに表示されている場合は、フェッチした行に対してさらにWHERE句の検索条件が適用されて行の絞り込みが行われるので、クライアントへ返される結果行は少なくなる可能性がある。

JOINを処理する場合、WHERE句により行の絞り込みがなければ最終的な結果行数の見積もりはJOINする全てのテーブルのrowsフィールドの積として考えることが出来る。PRIMARY KEYやUNIQUEインデックスを利用してJOINする場合、つまりレコードアクセスタイプがeq_refの場合rowsフィールドは1になる。上記、refフィールドの説明において用いた例がそうである。eq_refは理想的なJOINの形式であると言える。しかしレコードアクセスタイプがeq_ref以外の場合、例えばrefやrangeになってしまっている場合には前のテーブルに対して多数のテーブルがJOINされてしまうことになるので注意が必要である。

Extra

さて、今日の記事を締めくくるのはExtraフィールドだ。多くの人にとって、Extraフィールドはいろいろなコメントが表示される摩訶不思議なフィールドぐらいではないかと思う。しかし、Extraフィールドはその名前(Extra=追加情報)とは裏腹に、実はとても重要なフィールドなのである。

Extraフィールドは、そのクエリを実行するためにオプティマイザがどのような戦略を選択したかということを示すフィールドである。言ってみればオプティマイザの独り言のようなものであるが、Extraフィールドを見ればそのテーブルに対して何を行っているのかが如実に分かってしまうので、Extraフィールドを理解して初めてオプティマイザの挙動を理解したと言える。Extraフィールドを注意深く吟味することで、それぞれのテーブルがなぜこの順序でアクセスされているか?ということに対する理解に繋がるので、EXPLAINの出力結果全体を見通す際に役に立つだろう。

Extraフィールドに表示される代表的な追加情報を以下に挙げる。これらの情報は同時に複数表示される場合がある。

  • Using where・・・頻繁に出力される追加情報である。WHERE句に検索条件が指定されており、なおかつインデックスを見ただけではWHERE句の条件を全て適用することが出来ない場合に表示される。
  • Using index・・・クエリがインデックスだけを用いて解決できることを示す。Covering Indexを利用している場合などに表示される。
  • Using filesort・・・filesort(クイックソート)でソートを行っていることを示す。Using filesortについては先日詳しく説明したので参照されたい。
  • Using temporary・・・JOINの結果をソートしたり、DISTINCTによる重複の排除を行う場合など、クエリの実行にテンポラリテーブルが必要なことを示す。
  • Using index for group-by・・・MIN()/MAX()がGROUP BY句と併用されているとき、クエリがインデックスだけを用いて解決できることを示す。
  • Range checked for each record (index map: N)・・・JOINにおいてrangeまたはindex_mergeが利用される場合に表示される。
  • Not exists・・・LEFT JOINにおいて、左側のテーブルからフェッチされた行にマッチする行が右側のテーブルに存在しない場合、右側のテーブルはNULLとなるが、右側のテーブルがNOT NULLとして定義されたフィールドでJOINされている場合にはマッチしない行を探せば良い・・・ということを示す。

Extraフィールドにはまだまだバリエーションが存在するが、下記のページにまとめてあるので参考にして欲しい。MySQL 6.0で追加される予定のものについては書きかけだけど気にしてはいけない。
http://www.mysqlpracticewiki.com/index.php/Extra_field

注意点

EXPLAINを実行する場合、実際のデータを利用することが非常に大切である。なぜなら、テーブルの行数やインデックスの分散具合によって実行計画に違いが生じるからである。本番ではテーブルに100万行のデータが存在するのに、100行しかないテストテーブルを使ってクエリの最適化を行ってもあまり意味がない。

テーブルに対して大量のデータ追加、削除、変更などを行った場合、インデックスの統計情報が正確ではなくなる場合がある。そのような場合、ANALYZE TABLEコマンドを利用すると良いだろう。ANALYZE TABLEはテーブルの統計情報を更新してくれるコマンドである。

クエリを書き換えた場合にはEXPLAINの出力を見るだけでなく、正しい結果が得られるかどうかを確認しよう。いくら高速なクエリでも、正しい結果が得られなければ意味がない。

まとめ

EXPLAINコマンドの各フィールドの詳細を説明したが、実際にEXPLAINコマンドを使ってクエリの実行計画を見る際には次のようなステップを踏むといいだろう。

  1. id/select_type/tableフィールドを見て、どのテーブルがどの順序でアクセスされるのかを知る。これらはクエリの構造を示すフィールドであると言える。サブクエリが含まれている場合にはEXPLAINの表示順とアクセスされる順序が異なる場合があるので気をつける必要がある。
  2. type/key/ref/rowsフィールドを見て、各テーブルから行がどのようにフェッチされるのかを知る。どのテーブルへのアクセスが最も重いか(クエリの性能の足を引っ張っているのか)を、これらのフィールドから判断することが出来る。
  3. Extraフィールドを見て、オプティマイザがどのように判断して、各々のテーブルへのアクセスにおいて何を実行しているのかを知る。Extraフィールドはオプティマイザの挙動を示すものであり、クエリの全体像を把握するのに役立つ。

EXPLAINコマンドはクエリの実行計画を知るためのツールである。どのようにクエリを書き換えれば良いか?というのはまた別の問題であり、EXPLAINコマンドはどのようにクエリを書き換えればいいかについては何も教えてくれない。しかし、ただ一つ言えることはクエリにおいてテーブルからフェッチされる行数を減らすことが重要だと言うことである。

同じ結果が得られるなら、ひとつのクエリにおいてテーブルからフェッチされる行数が減れば減るほど良い。なぜなら、ストレージエンジンの性能には上限があるからである。例えば、あるストレージエンジンが1秒間に100万行のフェッチが出来る性能を持っているとすると、一つのクエリが平均1000行のフェッチを行うならば1秒間に最大1000クエリ、一つのクエリが平均100行のフェッチを行うならば1秒間に最大1万クエリが可能であるという計算になる。ひとつのクエリがフェッチする行数が減れば、クエリのレスポンスだけでなく全体のスループットも向上するのである。

そんなわけで、クエリを最適化したいならば、クエリを書き換えてはEXPLAINの出力と格闘しよう。その際にはこの記事を参考にしてくれると嬉しい限りである。

June 15, 2009

Windows API Code Pack for Microsoft .NET Framework (v0.9)

Filed under: ALL — Tags: , , — Sayuri @ 3:23 pm

Windows API Code Pack が v0.9 に更新されました。内容は以下の通りで、緑色がv0.85からの追加部分です。バグフィックスとともに、VBを含む新しいサンプルも追加されています。

Direct3D 10/10.1 も追加されました! D3DX10も含まれ、チュートリアルを含むサンプルもたくさん用意されているのでかなり役に立ちそうです。チュートリアルにはWinForm用、WinFormコントロール用、WPF用が用意されています。

しかしマルチタッチは含まれていません。.NET のマルチタッチについては、.NET Framework 4を待つしかないかもしれません。マルチタッチは Visual Studio 2010 Beta1 にもまだ含まれていませんでした。

  • Windows 7 タスクバー ジャンプリスト、アイコン オーバーレイ、プログレスバー、タブ サムネイル、サムネイル ツールバー
  • 既知のフォルダー、Windows 7 ライブラリ、非ファイルシステム コンテナ、シェル名前空間エンティティの階層
  • Windows 7 エクスプローラー ブラウザー コントロール
  • シェル プロパティ システム
  • Windows Vista と Windows 7 コモン ファイル ダイアログ(カスタム ファイル ダイアログを含む)
  • Windows Vista と Windows 7 のタスクダイアログ
  • Direct3D 11.0、Direct3D 10.0/10.1、DXGI 1.0/1.1、Direct2D 1.0、DirectWrite、Windows Imaging Component (WIC) API(DirectWriteとWICは部分的なサポート)
  • センサー プラットフォーム API
  • 拡張言語サービス API
  • 電源管理 API
  • アプリケーション再起動・リカバリー API
  • ネットワーク リスト マネージャ API
  • コマンドリンク コントロールとシステム定義シェル アイコン

ビルドには以下の環境が必要です。

  • .NET Framework 3.5 以上、
  • Windows SDK for Windows 7 RC
  • DirectX SDK (March 2009)
D3D10チュートリアル ビルド時の注意

Direct3Dでビルドするときには、DirectX SDKのインクルード フォルダとライブラリ フォルダを[ツール]→[オプション]から[プロジェクトおよびソリューション]→[VC++ディレクトリ]で追加する必要があります。

しかし、D3D10のサンプルをビルドしようとしたとき、なぜか「D3DX10.hが見つからない」というビルドエラーで失敗しました。Direct3DX10プロジェクトを右クリックして[プロパティ]を選び、[構成プロパティ]→[C/C++]→[全般]で、[追加のインクルード ディレクトリ]にDirectX SDKのインクルードフォルダ(C:\Program Files\Microsoft DirectX SDK (March 2009)\Include)を指定します。さらに[構成プロパティ]→[リンカ]で[追加のライブラリ ディレクトリ]にDirectX SDKライブラリフォルダ(C:\Program Files\Microsoft DirectX SDK (March 2009)\Lib\x86)を追加します。

image

D3DTutorial09_WPFの結果。ライティングが指定されていないので暗い。

June 13, 2009

WordPressサーバ移転まとめ (XREA)

Filed under: MYSQL, PHP, Wordpress — Tags: , , — Sayuri @ 4:33 pm

この土・日をかけてWordPressをホスティングしているレンタルサーバの乗り換えを行いました。ロリポも悪くないとは思うのですが、WordPressを運用していること、エントリ数も増えてきたこと、MySQLサーバが通常のサーバと別であることや1サーバあたりの収容人数が多いことなどを理由としてMySQLのレスポンスが日に日に遅くなってきたため、泣く泣く移転を決意しました(DBを使わないような静的ページのサイトであればリーズナブルでいいと思うんですけどね)。XREA+を選んだのはkohakuさん、bonoさんをはじめ多くの方がすでにWordPressの運用をされていて、MySQLのレスポンスも良好ということが決め手でした。

WordPressのサーバ移転をまとめます

実はWordPressのサーバ移転はこれが始めてではありません。ロリポのMySQL鯖が重くなってきた頃、MySQL鯖だけこっそりと新しいものに引越しをしていたのでした(  ̄ノ∇ ̄) ̄ー ̄)。そのときにきちんとメモを取っておかなかったため、今回も四苦八苦。きっちりとメモしておこうというのがこのエントリの趣旨です。
(と思っていたら、時を同じくしてlomoさんがXREA+に移転されていました。参照:WordPressの別サーバー移転メモ | caramel*vanilla。内容がかぶってしまっていますが、細々とやり方が違うので、情報を補完できれば…いいよね?)

旧サーバからDBをエクスポート

※以下、新サーバにとりあえずWordPressのインストールが終わっている状態で読み進めてください。DBごと旧サーバのものを書き込むので、細かい設定は不要です。XREAにWPをインストールして文字化けするようであれば、bonoさんところのハックを参照:power source* ≫ XREAにUTF8設置時の文字化け: 3)解決編:

WordPressのデータ本体はMySQLのDBにあるので、これを新サーバに持っていくことが目下の課題となります。WordPress 2.0にはdatabase backupプラグインというものも標準でついているのですが、これロリポでは動かないことが多いです(´;ω;`)。エントリ数が多いと負荷がかかりすぎて途中で止まってしまうんですね。ここでは通常通りphpmyadminを使ってエクスポートします。

phpmyadmin

phpmyadminにログインするとこんな感じの画面が表示されると思うので、左の赤枠の部分(データベース名が表示されていると思います)をクリック。

phpmyadmin

すると右フレームの画面が上の画像のようになるので、さらに赤枠のエクスポートをクリック。

phpmyadmin

上の写真の画面では、赤枠の『「DROP TABLE」を追加する』と『ファイルで保存する』にチェック。エクスポートのところにTABLEのリストが表示されるので、エクスポートしたい必要なTABLEだけを選んでやります(CTRLを押しながらクリックすることで、複数選択できます)。最低限必要なのは、

  • wp_categories
  • wp_comments
  • wp_linkcategories
  • wp_links
  • wp_options
  • wp_post2cat
  • wp_postmeta
  • wp_posts
  • wp_usermeta
  • wp_users

の10個かな(wpの部分は設定のプレフィックスによって違います)。このほかにも利用しているプラグインによっては選ぶものが増えると思います。私はUltimate Tag Warriorを使っているので、

  • wp_post2tag
  • wp_tag_synonyms
  • wp_tags

の3つもエクスポートしてやりました。stattraqやbstatsのログはすべて諦めます…。容量大き過ぎです…。

wp_optionsにちょこっとおまじない

今の状態は旧サーバで公開している状態だと思うので、このままインポートしてしまうとWordPressの管理画面にログインできなくなってしまいます。DBの文字コード(おそらくUTF-8かEUC-JP)を扱えるエディタでさきほどエクスポートしたファイルを開いてやります(サクラエディタhiromasaさんオススメ)。「wp_options」で検索すると、
INSERT INTO `wp_options` VALUES (1, 0, 'siteurl', 'Y', 1, 'http://www.oldserver.yo/', 20, 8, 'WordPress のアドレス', 1, 'yes');

INSERT INTO `wp_options` VALUES (40, 0, 'home', 'Y', 1, 'http://www.oldserver.yo', 20, 8, '', 1, 'yes');
という二つの文に旧サーバ名が見つかるかと思います。ここがそれぞれ管理画面>一般設定の「WordPressのアドレス」、「ホームページアドレス」に対応しているので、ここに新サーバでの「WordPressシステムのあるアドレス」、「公開したいアドレス」を書き込みます。WordPressシステムの場所と公開したいアドレスが一緒の場合は同じものになります。私の場合、http://odyssey.sxxx.xrea.comです。ドメインで公開したい場合も今は新サーバでもらっているアドレスを暫定的に入力しておきます。すべての設定が終わった後でドメイン名に変えてやればOKです。

新しいサーバにDBをインポート!

ファイルを保存したら、新サーバにphpmyadminを開き、一旦現在あるDBのテーブルを削除してやります。すべて綺麗になったところで改めて、さきほどのDBのファイルをインポート。

phpmyadmin

うまくインポートできたら、新サーバのWordPressにアクセスしてみましょう。ここまでうまくいっていれば、アドレス以外は今までと同じ状況が復元できていると思います。

※phpmyadminのDBが文字化けしているようであれば、phpmyadminをハックすることで対処できます。(ファイルの位置はご自分の環境に合わせて読み替えてください。例はXREAの場合です)/public_html/log/phpmyadmin/librariesにあるdatabase_interface.lib.phpの中に
PMA_DBI_query('SET NAMES ' . $mysql_charset . ';', $link,
PMA_DBI_QUERY_STORE);

という二行があるので、この二行をコメントアウト(先頭に//を付加)してやればOKです。

最後にドメイン設定して完了

残りは簡単。新サーバ側でネームサーバを設定(XREAはここで新規ネームサーバを作成)。わたしはロリポのときにmuumuu-domainにてドメインを管理しているので、これをそのまま使ったため、以下のようにDNSを変更。

phpmyadmin

さらに、XREA側でドメインウェブの設定をしてやればOK!(XREAコンパネ→マイドメイン利用→ドメインウェブ)以下のようにすると、XREAのアドレスを維持しながら、www付ドメイン、wwwなしドメインのいずれからもアクセスできるようになります。

phpmyadmin

おつかれさまでした!

日曜日長々とお付き合いくださった、hiromasaさん、kohakuさん、akaさんありがとうございました!

Essential .NET 4.0 for C# Developers Training Course – DevelopMentor

Filed under: Asp.Net, C# — Tags: , , , , , , , — midori @ 3:47 am

,ASP.NET,JAVASCRIPT,JQUERY

NET and the Entity Framework; Build web sites with ASP.NET MVC; Build rich client and rich internet applications using Silverlight 4.0; Design and build web services using WCF ; Leverage the power of multi-threading and thread-safety in …

NET and the Entity Framework; Build web sites with ASP.NET MVC; Build rich client and rich internet applications using Silverlight 4.0; Design and build web services using WCF; Leverage the power of multi-threading and thread-safety in …

Read more:
Essential .NET 4.0 for C# Developers Training Course – DevelopMentor

June 7, 2009

Wordpressが使える初心者向けレンタルサーバー  PHP&MySQLについて

Filed under: LAMP, MYSQL, PHP, Wordpress — Tags: , , — Sayuri @ 6:30 am

(1)WordPressを動作させるために必要な条件が揃っているか・・最重要!

WordPressの最新バージョン2.7.1を動作させる為に必要なサーバー環境は、

* PHP version 4.3 以上
* MySQL version 4.0 以上

となっています。参照 http://wordpress.org/about/requirements/

『PHP version』とは、WEBサーバー上でPHPファイルを動作させるための仕様を表す数値であり、『MySQL(マイエスキュール)version』は、データベースを運用するシステムの仕様を表します(これらはサーバー会社の範疇であり、ユーザーが直接操作することはありません)

これらの数値は、サーバーの品質や機能を知る一つの手掛かりとなり、数値が大きいほど新しいバージョンを意味します。

2009年3月現在、PHPの最新版は5.3系です。

WordPress自体は、4.3以上で動作が確認されていますが、バージョンがあまりに古いと、他のPHPファイルで書かれたプラグインやプログラムが動作しなくなる場合があるので、なるべく新しいバージョンのものを選びましょう。
できれば、「5」以上が望ましいです。

MySQLに関しては、多くのレンタルサーバーが最新の5.0系を取り入れており、まず問題になることはありませんが、サーバー会社の中には、MySQLすなわちデータベースの使用は『別途料金』で設定しているところもありますので、初心者はしっかり確認しましょう。

PHPおよびMySQLに関する情報は、レンタルサーバー公式サイトの「使える機能」「サーバースペック(仕様)」「サービス概要」といった項目に必ず記載されています。

「PHP → 使用可」「MySQL → 使用可」であり、なおかつバージョン数値が上記の条件を満たしていれば、WordPressをインストールしてデータベースを作成することができます。
サーバーの中には、バージョンの数値を明記していないところもありますので、気になる時は、サーバー会社に直接問い合わせましょう。

作成できるデータベースの数は、格安サーバーであれば「1つ」のところが多いですが、初心者には「1つ」で十分です。(後から1つのサーバーに複数のWordPressをインストールして、マルチブログ化を図ることも可能です)

(2).htaccessが使用可能か

『.htaccess』とは、WEBサーバーの動きをディレクトリ単位で制御する隠しファイルです。

WordPressでパーマリンクを設定する為に欠かせない機能です。

WordPressのデフォルトのURLは、『http://example.com/?p=123』のようになっていますが、これでは訪問者が覚えにくい上、検索エンジン対策にも不利なので、多くのユーザーは、.htaccess機能を使って、分かりやすいパーマリンクに置き換えています(『http://example.com/movie』など)

「絶対的に必要」というわけではありませんが、後々、他のプログラムを動かしたりするのに必要になってくるので、やはりおさえておきたい機能です。
さらに詳しく言えば、『mod_rewriteという機能が使える』ことが重要です。

多くのWordPressユーザーが利用しているレンタルサーバーでは、.htaccessを使ってパーマリンク設定が可能ですが、中には、セキュリティの問題から使用を禁じているサーバーもありますので、どうしても設定できない時はこちらの記事を参考にして下さい。
『mod_rewriteが使用できないサーバーでのパーマリンク設定』

(3)管理画面は使いやすいか?

たいていのレンタルサーバーは「My管理画面」を持っており、ログインすれば、ファイル容量を確認したり、データベースにアクセスしたり、メールアカウントを設定したり、いろんな機能が使えるようになっています。

しかし、中には、高機能ながら玄人向けで、初心者には何が何のことだか分からない・・という場合もあります。

サーバーの質が良くても、管理が負担に感じられると、モチベーションの低下につながるので、管理画面が使いやすいサービスを選ぶのも一つのポイントだと思います。

(4)サーバーがいつも混み合っていないか?

たいていの格安レンタルサーバーは、1つのサーバーを数十名が共有するシステムになっています(共用型サーバー)。

お試し期間中にいろんなファイルをアップして、「転送速度が遅い」「すぐ接続が切れてしまう」といった問題が多いようなら、考えた方がいいと思います。

WordPressの場合、記事投稿、管理編集、サイト表示など、すべてはサーバーの処理能力に依るところが大きいので、一つ一つの動作が重いと、それだけで負担になってしまいます。

「サイトの表示に時間がかかり過ぎ、すぐエラー画面になる」といった不満が多いと、アクセス低下の原因にもなりますので、サーバーの処理能力が優れたサービスを選びましょう。

(5)サポート体制は十分か

どこのレンタルサーバーもサポートには力を入れていますが、「FAQが分かりやすい」「WordPressに関する情報が充実している」「メールの問い合わせにすぐ応じてくれる」というのも一つの目安です。

(6)その他・・

容量は多い方がお得な気がしますが、普通にテキストを入力するだけならほとんど容量は食いません。

一日原稿用紙4~6枚ぐらいの日記を500日分書いても、50MBいくか、いかないかぐらいです。

私のサイトも現在600本近い記事がありますが、WordPressが使用しているデータベースの大きさはたったの53MBです。

サーバー容量を食っているのは画像と動画です。あと、アクセス解析のログもかなり容量を食います。

ですから、テキスト主体のブログで、画像は適当に縮小したものを記事に1つか2つ、あとはアフィリエイトのコードを貼り付ける程度なら、数Gも要りません。

どうしても容量が欲しくなったら、増量サービスで追加するか、時期を見てワンランク上のサーバーに引っ越せばいいので、最初からあわてて中級クラスの大容量サーバーを借りる必要もないと思います。

もちろん、フォトギャラリーを主体にしたい方や、動画アフィリエイトに取り組みたい方は、最初から容量をたっぷり確保するのも一つの考えだと思います。

でも、一番大事なのは、「ピン」とくる相性かもしれません。

すごく評判が良くても、「自分には使いにくい」とか、「重く感じる」とか、相性ってありますのでね。

触ってみて、「なんとなく居心地が良い」。それで決めるのもアリだと思います。

やはりサイト運営の核となるサーバーですので、長く、親しく、お付き合いできるサービスを選ぶことが肝心です。

万一、途中でサーバーに不具合を感じて、他のサービスに変わりたくなっても、WordPressの場合、わりと簡単にデータ移行ができるので、そこまで深刻に考えなくても大丈夫です。

独自ドメインなら、サイトURLを変更することなく、サーバー移転が可能です。

初心者向けのサーバー

・表示している情報や数値は、「WordPressを使用する場合」を前提としています。
・サーバー容量は、初心者向けの数値をピックアップしています。(各社とも豊富なプランが有ります)
・初期費用・月額は、キャンペーン、パック割引などにより随時変動します。
・下線リンク部は、各サーバー会社の説明ページに飛びます。
・紹介しているサービスはいずれも『無料お試し期間』があります。詳細は会社サイトにてどうぞ。

June 3, 2009

【HOW TO】MySQLを高速化する10の方法

Filed under: LAMP, MYSQL — Tags: , , — doku @ 9:13 pm

ちょっとキャッチ−なタイトルをつけてしまったが、今日は独断と偏見でMySQLを高速化する方法を10個紹介しよう。MySQLサーバをチューニングするときや初期導入する場合などに参考にしてもらいたい。

1. バッファを増やす、または減らす

チューニングの基本中の基本であるが、適切なバッファサイズを設定することはパフォーマンスチューニングの要である。主なバッファは次の通り。

  • innodb_buffer_pool_size・・・InnoDBだけを利用する場合は空きメモリの7〜8割程度を割り当てる最も重要なバッファである。余談だが、実際にはここで割り当てた値の5〜10%ぐらいを多めにメモリを使うので注意が必要だ。
  • key_buffer_size・・・MyISAMだけを利用する場合は、空きメモリの3割程度を割り当てるといい。残りはファイルシステムのキャッシュ用に残しておこう。
  • sort_buffer_size・・・ソート処理に利用するバッファである。OLTPでは256K〜1Mぐらいを割り当てると良い。これがあまり大きすぎると、メモリの割り当てのオーバーヘッドが大きくなるので注意しよう。DWH系の処理などで大きなソートが必要な場合、セッションごとに動的に調整すると良い。
  • read_buffer_size・・・全件スキャンをするときに利用するバッファ。OLTPでは128K〜512Kぐらいを割り当てると良い。
  • read_rnd_buffer_size・・・ソート処理でインデックスを利用する場合に利用するバッファ。OLTPでは256K〜1MぐらいをDWH系の処理などで大きなソートが必要な場合、セッションごとに動的に調整すると良い。

バッファは増やせば増やすほどいいかと言えばそうではない。メモリの割り当てがオーバーヘッドになるので、無駄に大きくし過ぎることは禁物である。また、バッファを増やしすぎたためにスワップが発生するとパフォーマンスが悲惨なことになるのでくれぐれも空きメモリ容量には注意しよう。

2. 高速なディスクを利用する

MySQLだけに限った話ではないが、RDBMSのボトルネックは99.99999%がディスクI/Oである。特にディスクのシークタイムによる待ち時間が大きい。理想的にはバッテリーバックアップ付きのRAID装置を利用するのがいい。最近はRAID装置に匹敵するほど高速なSSDが出てきているので楽しみである。

前述のようにバッファを大きくするとディスクI/Oの回数や量が減るので、必ずしも高速なディスクが性能を向上させるというわけではないが、データサイズが大きくてバッファに収まりきらない場合などにはどうしてもI/Oが大量に発生してしまう。そんな時は高速なディスク装置を利用するといい。

3. クエリを最適化する

実は最も大事なのがクエリの最適化である。いくら他の部分を最適化したところで、毎回全件スキャンが発生していたのでは話にならない。適切にインデックスを使ったり、サブクエリをJOINに書き換えたりすることで、フェッチしないといけない行数ができるだけ少なくなるようにクエリを書きかえよう。クエリを最適化するには、まずEXPLAINで実行計画をチェックしよう。EXPLAINの見方についてはいずれ解説しようと思う。

また、テーブルから全件フェッチしてからアプリケーション側で行を絞り込むというようなロジックを実装してはいけない。必ずSQL文、つまりWHERE句で行の絞り込みができるようにしよう。

クエリを手当たり次第チューニングしていてはいくら時間があっても足りないだろう。問題のあるクエリだけをチューニングするべきであるが、そのようなクエリを見付けるにはスロークエリログや商用のクエリアナライザを用いると効果的である。

4. テーブルを最適化する

基本中の基本は、適切なデータタイプを使うということである。できるだけカラムサイズが小さくなるようなデータタイプを選ぼう。数値をVARCHAR(桁数)などのデータタイプで格納しているのをたまに見かけるが、これは誤りである。INTまたはBIGINTなどを利用したほうがずっとデータサイズが小さくなるし高速である。

また、適切なカラムに対してインデックスをつけるのも重要である。どのカラムにインデックスをつけるかは、クエリのパターンに因る。インデックスが多すぎると更新時のオーバーヘッドが大きくなるだけでなく、インデックスツリーを格納するためのデータ容量が増えてしまうので、インデックスのつけすぎには注意しよう。たまに全てのカラムにインデックスがついているテーブルを見かけるが、そのようなテーブル設計は誤りである。クエリのパターンによっては、マルチカラムインデックスやパーティショニングが必要になるなどいろいろと工夫が必要になる。

カラム数がが多くなりすぎたら、まずは正規化できるかどうかを検討してみて欲しい。DWH用途などでは逆に非正規化すると性能が向上する場合がある。

5. 目的に合ったストレージエンジンを選択する

これはMySQLの醍醐味である。ストレージエンジンはそれぞれ性能特性がまったく違うので、目的に合ったストレージエンジンを選択すると劇的に性能が向上する場合がある。例えば、OLTPではInnoDB、参照系が多い場合はMyISAM、ログ目的であればARCHIVE、リアルタイム並列処理であればNDBCLUSTERなど。他にもSun/MySQL以外のサードベンダーやコミュニティからリリースされているストレージエンジン(SPIDER、PBXT、XtraDB、Q4M、Infobright、Kickfireなど)もあるので、目的に合わせて色々検討してみるといいだろう。

6. レプリケーションで負荷分散する

MySQLほどお手軽に、そして安価にレプリケーションを利用出来るRDBMSは他にないだろう。レプリケーションを用いてたくさんのスレーブへ参照系の処理を負荷分散するテクニックは、Webサイトなどで頻繁に利用されているテクニックである。参照系の負荷分散を行う場合だけでなく、例えばOLTPのデータを元にBIなどの処理を毎日行う場合などにも有効である。スレーブ上でBIを行えば、マスター上のOLTP系の処理に影響を与えることがない

7. ストアドプログラムを多用しない

残念ながら、MySQLはストアドプロシージャ、ストアドファンクション、トリガなどの性能はあまりよくない。出来るだけそれらを利用せずに、ロジックをアプリケーション側に持っていくといいだろう。

8. ファイルシステムをチューニングする

Linuxであればデフォルトはext3(そろそろext4になっていくだろうか?)であるが、ext3ではなくXFSを利用すると性能が向上する場合がある。また、I/Oスケジューラを変更することで、同じext3であっても性能特性が変化する。SolarisではUFS、ZFS、QFSなどの利用を検討するといいだろう。WindowsならNTFS以外にあまり選択肢はないが、MyISAMの場合はLargeSystemCacheを有効にするなどのチューニングが必要である。

9. コネクションプールを利用する

アプリケーションがDB操作が必要なときに都度MySQLサーバへ接続していたのでは、接続のためのオーバーヘッドが無視出来なくなる。そんなときはコネクションプールを利用するといい。

10. ベンチマークする

どんなチューニングでも、実際に効果があるかどうかは測定してみるまで分からない。また、あるアプリケーションで効果があるチューニングでも、他のアプリケーションの負荷パターンでは逆効果になってしまうということは多々ある。なので、アプリケーションの負荷を擬似的に作り出してチューニングの効果を測定することはとても重要なのである

Older Posts »

このページの上部に戻る

Powered by WordPress