スキップしてメイン コンテンツに移動

投稿

Javascriptで動作するHTMLエディター

Web画面上でHTMLを編集するために、Javascript実装のHTMLエディタが必要になることがあると思います(例えばWordpressやBloggerのエディタのようなものです)。 様々なエディタがありますが、 Code Mirror というエディタは高機能で便利です。下記のような機能があります。 100以上の言語をサポート 強力なxmlタグ補完機能 コード折り畳み機能 Vim、Emacsなどと同じキーバインディングのサポート 検索・置換機能 括弧、タグのマッチング機能 たくさんのアドオン

XMLStarletを使ってLinuxのコマンドラインからXMLを操作

LinuxのコマンドラインからXMLを操作する際には、 XMLStarlet を使うと便利です。 ただし、複雑な処理を適用する場合は、素直にプログラミング言語で提供されているDOMやParserを使う方が良いと思います。 例えば、下記のコマンドを実行すると、特定のxpathにマッチした要素の数を数えることができます。 # selはxml documentへのクエリや検索を実行するためのオプション # -tはテンプレートを指定するためのオプションで、下記の例では、さらに-vで指定したxpathを実行するように命令しています。 xml sel -t -v &quote;count(/xml/table/row)&quote; data.xml オプションは色々あるので、公式ドキュメントを読んで色々試してみるのが近道かと思います。

Nexus 7 (2012) に Android 7.1.2を無理やり導入したときに発生したバッテリの消費問題

Nexus 7 (2012)にAndroid 7.1.2を適用 長年愛用しているNexus 7 (2012)は公式にはAndroid 5.1.1でサポート打ち切られていますが、 調べたところ、下記の記事から有志の作ったAndroid 7.1.2 AOSPを焼けることがわかり早速試してみました。 https://ameblo.jp/nattolecats/entry-12307126801.html Nexus 7 (2012)上でAndroid 7.1.2を通常動作させるところまで行き、満足していました。(動きは比較的軽快でした。)   ところが!  Android 7.1.2 適用前よりも、スリープ時に「Miscellaneous(=雑多)」とい う項目でバッテリがどんどん消費されてしまうという問題が発生し、原因の解明に四苦八苦することになりました orz スリープ時のバッテリ消費の原因 結論から言うと、私の適用したROM ( aosp_grouper-7.1.2-ota-eng-20170811.ds.zip  )のビルドタイプがuserdebugになっていたこと原因でした。 ro.build.type=userdebug どうもデバッグ用の何らかのプロセスが走って、電力を消費してしまうようです。 通常は、 ro.build.type=user です。というわけで、このro.build.typeを書き換えればいいのですが (例えば BuildProp Editor を利用)、build propertyは、root権限がないと書き換えられないため、今度はroot化必須、、、となったところで私は「もういいやwww」となりました。 最終的には、Googleから公式の提供されているFactory Image "nakasi" for Nexus 7 (Wi-Fi)   をGoogle先生の言われたとおり適用して、まっさらな Android 5.1.1状態で使うことにしました。動作がもっさりしていたり、最新のアプリがインストールできなかったり、セキュリティ大丈夫なのか、とかいろいろ問題ありますが、自分はNexus 7を読書用と割り切って使うことにしました。 ...

MySQLのSQL_CALC_FOUND_ROWS使用上の注意

MySQLのSQL_CALC_FOUND_ROWSを使用する際の無駄なメモリ消費に注意 ページング機能の実装などのために、ヒットした全件数を取得する必要のある場合があるかと思います。 その場合、下記のようにSQL_CALC_FOUND_ROWSを使うと、検索結果に加えて、そのクエリの全ヒット件数が取得できます。 SELECT SQL_CALC_FOUND_ROWS table.column1, table.column2 ...(途中省略)... FROM table WHERE (条件) しかし、SQL_CALC_FOUND_ROWSを使うと、「絞り込んだ結果にヒットする全べての行の結果のセットを作成する」という大きな欠点があります。 これは、LIMIT, OFFSETを指定していても実行されてしまうので、 SELECTで指定するカラム数やデータ量が多い SELECTの結果返ってくる行数が多い 場合、無駄に領域(≒メモリ)を消費してしまうので注意が必要です。 例えば、100万行検索対象としてヒットするクエリの場合、仮にLIMIT 20と指定して最初の20行を取得するようにクエリを書いても、その100万行分の結果セットが作成されてしまうということになります。 対応策 根本的な対応策としては、SQL_CALC_FOUND_ROWSを使わない(結果行数の取得はCOUNTを用いた別クエリで取得する、結果行数をあらかじめサマリーテーブルに保持しておく)ことですが、 SQL_CALC_FOUND_ROWSをどうしても使う必要がある場合は、 SELECT SQL_CALC_FOUND_ROWS primary_id のように最低限のカラムを指定して結果行セットを取得 (LIMIT OFFSET指定前提) 取得したprimary_idを使って必要なデータを取得 して、SQL_CALC_FOUND_ROWSで使用する領域をできるだけ減らすことで、対応するしかないと思います。 世の中ではLIMIT, OFFSETは使わない方がよいとよく書かれていますが、 SQL_CALC_FOUND_ROWSは、書いてしまえばどんなときも検索にヒットする全結果行セットを作成するので、同じくらい使用する際には注意が必要です。

MySQL: SELECTの結果をUNIONして ORDER BYする際の最適化方法

SELECTの結果をUNIONして ORDER BY する際には下記の点に注意する必要があります。 無駄なメモリ消費 ソートにINDEXが利かない (≒CPU負荷増大) 対応策 可能であればPush-down Condition (各サブクエリ内でORDER BY, LIMIT, OFFSETを適用してからUNION, ORDER BYを実行する)を利用することで、 パフォーマンスを改善できる場合があります。 下記に例を示します。 もともとのクエリ SELECT tmp.* FROM ( SELECT tableA.column1, tableA.column2 FROM tableA WHERE (条件) UNION ALL SELECT tableB.column1, tableB.column2 FROM tableB WHERE (条件) ) AS tmp ORDER BY tmp.column1, tmp.column2 LIMIT 100, 20 Push-down Conditionを用いて書き直したクエリ SELECT tmp.* FROM ( SELECT tableA.column1, tableA.column2 FROM tableA WHERE (条件) ORDER BY tableA.column1, tableA.column2 LIMIT 30 # ただしこのPush-down Conditionの手法も下記の場合は、効果が半減しますので注意が必要です。 OFFSETの値が大きい場合は、結局全結果セットUNIONと変わらない サブクエリ内のソートで、INDEXが効かない場合

MySQLのクエリチューニングの基本的な考え方

今回は、筆者が気をつけている、MySQLのクエリチューニングの基本的な考え方について、紹介しようと思います。 基本的な指針としては、下記を守ることが重要です。 MySQLがクエリの実行で使用する領域(≒メモリ使用量)を減らす。 クエリ対象の行を減らす (INDEX, サマリーテーブルを駆使)。 上記の基本的な指針に基づいて、クエリを組み立てる際は以下の点を考慮するとよいと思います。 SELECTで指定する行は少なくする。 JOINするテーブルの数は減らす。 TEXTや大きいサイズのVARACHARでのORDER BYは極力避ける。SUBSTRなどを使ってカラムの一部データのみを使うことも考慮。 EXPLAINを実行した際に Extra: Using where; Using temporary; Using filesort と表示される場合は要チェック。 確認部分: 巨大なTemporaryテーブルが作成されないように注意。 対策: 「ソート部分でINDEXを使えないか」「サマリーテーブルを使って余計なJOINを減らしソート対象の行数を減らせないか」を検討。 INDEXを効かせる。 テーブル設計段階でどのカラムにINDEXを張るかをしっかり検討 (当たり前ですが。) 特にソートの必要がある場合は、できるだけINDEXやPRIMARY KEYを利用できるようにクエリやテーブルを設計。 基本MySQLのクエリオプティマイザに従うべきですが、あえて特定のINDEXを効かせる/効かせない場合は FORCE INDEX STRAIGHT_JOIN の利用も検討。ただし、クエリの実行プランはデータによっても変わるので、基本、FORCE INDEXやSTRAIGHT_JOINは使うべきではないと筆者は考えています。 想定される状況が限定的 解決しようとしているクエリの問題が明確 性能改善度合いが大きい ときのみ、FORCE INDEXやSTRAIGHT_JOINは使用すべきかと思います。また強制したクエリの実行プランが最悪の実行プランになった場合も想定することをお勧めします。 複雑なネストクエリは避ける。 確認部分: Temporaryテーブル(INDEXが効かない!)が作成される可能性が高い上、メモリも大量に...

Java 8の機能利用に伴うSpring 4へのバージョンアップ

下記の順序で環境を更新していったときに、問題が起こったのでメモしておきます。 Spring 3 + Java 7: もともとの環境。 Spring 3 + Java 8 (Java 8のラムダ機能などのJava 8からの新機能は未使用): 問題なく動作。 Spring 3 + Java 8 (Java 8のラムダ機能などのJava 8からの新機能を使用): 起動時に下記のExceptionが発生 org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL ...(途中省略)... java.lang.ArrayIndexOutOfBoundsException: xxx Googleで調べたところJava 8から導入された新機能を使う場合は、Spring 4に更新しないといけないようです。 Mavenとかは、使っていなかったので、Spring Frameworkから提供されているspring-xxx系のjarすべてをバージョン3.X系からバージョン4.X系のものに手動で置き換えました。 (Spring Frameworkはバージョン5.X系ももう出ているのですね。既に置いていかれているorz...) 無事にアプリケーションが起動するようになりました! ただ普通は、こんな乱暴にjarを入れ替えることは難しいので、アップデートはもっと慎重にやるべきでしょうね。