MySQL」タグアーカイブ

PHPでSQL文を実行するときは、ほどよく改行

私がPHPを使いはじめて間もないころ、仕事でMySQLを使うことになりました。

そのときはSQL文については知識が多少あったので、順調にシステムを構築していました。

ところがっ!!

あるとき、どーしてもエラーになってしまうSQL文が出てしまい、原因が分からずかなり悩んだ記憶があります。

当時、私はPHPのソースをとりあえずがむしゃらに書くことに専念していて、後で見ることに対してはまったく気にせず、ただ打ち込むことだけをしていました。

そのエラーが発生するSQL文を見ると・・・

$sql = “SELECT ・・・・・・・・・・・・・・・・・・・・・・・・・・・”;

改行をいれることなくただ、横に長~く書き込んでいました。

あるとき、何を思ったか改行コード(\n)を入れて見やすくしたころ、エラーもなく問題なくSQL文は実行されました。

私の知る限り、私が見てきた書籍にはSQL文中に改行がなく長いSQL文の場合はエラーとなるなんて書いてなかったです。(←常識なのかもしれません)

こんな、トラブルに見舞われるのは私ぐらいかもしれませんけど、みなさんソースは見やすくかきましょうね。

MySQLで数字のソート

MySQLを使っていて抽出したデータを並び替えるというのはごく一般的に使われると思います。
例えば、INT型のカラム名Aというものを昇順にならび替える場合はSQL文に
「 ORDER BY A 」と追記してあげれば正常な結果が出てきます。
ただ、私の場合はVARCHAR型のカラム名Bのデータを昇順に並び替える必要が出てきたことがあります。
単純にORDER句を使えば正常な結果が出てくるのですが、そのBに入っているデータは数字であったり文字であったりしています。
例えば、「第1号」とか「第234号」とか。
この並び替えをORDER句を使って実行すると先頭からの文字でソートされてしまいます。
1「第1号」
2「第11号」
3「第111号」
4「第2号」
という感じです。
これを、番号順に並び替えるにはどうすればいいか。

答えは、桁数順→数字順とすれば正常に抽出されます。
SQL文では「SELECT * FROM table ORDER BY LENGTH(B)、B」
という感じです。
LENGTHでカラムBの文字数順に並び替えてくれます。

ただ、一点未解決の部分がありまして、「第10−1号」の場合はどうするか?
これは、PHP側でデータを取り込む際もしくは、抽出したデータを再度並び替えすることで対応しました。

MySQL入門書

私は今はWEB開発中心なのでMySQLを主に使っていますが、一番最初に勉強したきっかけは求人の備考欄に「SQL経験者」とあったからなんですよね。
当時は、SQLとは??と言った感じで高校のときに第二種情報処理技術者試験を受けるときに勉強した程度で、それ以降さっぱり使うこともなかったものです。

そんな私ですから、SQL経験者なんて書かれていると焦ります。
そもそも当時はソフト側の人間ではなくハード側の人間でしたから。

とりあえずSQLとはなに?の勉強に使用したのが「基礎SQL」という本でした。
ほんとに基礎から載っているんですが、文字も大きく基礎部分だけしか載っていないので覚えるには最適でした。

MySQLもPostgresSQLもORACLEも結局基礎のSQLはほとんど変わらないですからね。
これから、SQLの勉強を始めようって人にはオススメではないかと思います。

MySQLチューニング

MySQLって軽快な動作をすると評判らしいのですが、チューニングをしてあげないと意味がないんですね。

最初はデフォルトの状態で運用していたのですが、レコード数が増えるにしたがって遅くなってしまう。そこで、いろいろと調べると設定ファイルを調整してあげれば格段に軽快な動作をするようになりました。

以下は私が設定した例です。

※設定はあくまで例です。参考程度にして下さい。

#スロークエリログ設定
log-slow-queries
long-query-time=30
log-long-format

#SELECT文をキャッシュ
query_cache_size=32M

#インデックスを用いないテーブル結合のときに使われるメモリ上の領域
join_buffer_size=8M
#インデックスを用いないテーブルスキャンのときに使われるメモリ上の領域
read_buffer_size=8M
#ソート後にレコードを読むときに使われるメモリ上の領域です。
#ディスクI/Oが減るのでORDER BYの性能向上が期待できます。
read_rnd_buffer_size=32M
#最大コネクション数
max_connections=50

#メモリに余裕がある場合に指定。検索に使われるインデックスをバッファに保存する際のメモリサイズ
key_buffer=32M
#入力データ保持のための最大バッファサイズ。画像など、大きなデータ挿入でこの制限に引っ掛かる可能性がある
max_allowed_packet=1M
#頻繁なアクセスに対し、データのキャッシュでディスクのI/O負荷を減らす場合に使用
table_cache=256
#頻繁なアクセスに対し、データのキャッシュでディスクのI/O負荷を減らす場合に使用
sort_buffer_size=16M
#値を大きくすることでインデックスを含まないクエリーの実行速度を上げる
record_buffer=1M

# スレッドの作成,削除は負荷が大きい.
# Threads_Createdの動きを見ながら変更.
thread_cache=16

# You can write your other MySQL server options here
#                                  Datafile(s) must be able to
#                                  hold your data and indexes.
#                                  Make sure you have enough
#                                  free disk space.
innodb_data_file_path = ibdata1:100M:autoextend:max:10000M
# InnoDBはOSキャッシュを使用しないため,全メモリの70-80%を当てると良い.
innodb_buffer_pool_size =128M
#InnoDBの内部データなどを保持するための領域
innodb_additional_mem_pool_size=10M

 

その他に「ここも設定したほうがいい」という項目があったら教えてください。