helloworlds

not a noun, it's a verb

TCP/IPまわりについてメモしてみた

プロトコル

まずWikipediaにはこう書かれている。

プロトコル - Wikipedia

もともとは「人間どうしのやりとり」 ITの分野で生まれた言葉ではないようですね、なるほど。

現在では、電子機器が相互に通信する際に用いられる通信規約としてプロトコルという言葉を使用している。

そして通信を行うときには様々なプロトコルを組み合わせる。これをプロトコルという。

インターネットに関するプロトコルとして代表的なのが、以下。

TCP/IP

TCP/IP参照モデルとは、IETF (日本語はこちら)により管理されている、 インターネットで使われる4階層のプロトコル群のこと。 どうやらこのモデルを作成したのは、DARPA(米国国防高等研究計画局)というところみたいだ。

階層 名前 代表プロトコル
第4階層 アプリケーション層 HTTP,SMTP,DNS,FTP,SSH,TELNET...
第3階層 トランスポート層 TCP,UDP
第2階層 インターネット層 IP,ICMP,IGMP
第1階層 リンク層 ARP

アプリケーション層

主に2つのカテゴリがあって、ユーザに直接サービスを提供するユーザプロトコルと、 共通的なシステム機能を提供するサポートプロトコルがある。 どのような形式や手段でデータをやり取りするのかを決めるところと覚えておきます。

トランスポート層

通信を行うプログラムの間でのデータ伝送を実現する。 アプリケーションのためにend-to-endの通信を提供する。

インターネット層

複数のネットワークを相互に接続したインターネットワークで、機器間のデータ伝送を実現する。 ICMPは制御プロトコルであり、IPの上の層に位置するが、インターネット層に属する。

リンク層

ネットワークインターフェースのためのプロトコル。 ネットワークハードウェアが通信を実現するための層で、各種イーサネット無線LANなどがこの層に属する。

このモデルと同様によく出てくるのが、以下。

OSI

OSI参照モデルとは、ISO(国際標準化機構)によって策定された7階層で構成されたプロトコルのモデル。

階層 名前 説明 ネットワーク機器
第7階層 アプリケーション層 具体的な通信ハブ L7/LB
第6階層 プレゼンテーション層 データの表現
第5階層 セッション層 通信プログラム間の通信の開始から終了までの手順
第4階層 トランスポート層 ネットワークの端から端までの通信管理 L4/LB
第3階層 ネットワーク層 ルーティング、データ中継 L3/ルータ
第2階層 データリンク層 直接的に接続されている通信機器間の信号の受け渡し L2/スイッチングハブ,ブリッジ
第1階層 物理層 物理的な接続でコネクタのピンの数など L1/リピータハブ

基本的にTCP/IPOSIの示していることは中身は違えど存在意義は同じですね。 TCP/IPの方が実用性に長けているようです。 似ているのだから1つにすればいい、と思うかもしれませんが、それは歴史を知るといいかもしれません。(ポステルの法則)

一旦はこうした概念がることと、どこの階層でどんなことが行われているのか理解しておけばいいかな〜。

TCP/IP

TCP(Transmission Control Protocol)は、(TCP/IP参照モデルの)トランスポート層に属するコネクション型プロトコル。 Webやメール、FTPなどといったクライアントちサーバ間で双方向通信を行うサービスである。

  • パケットを送信する際、シーケンスナンバーを都度更新し送信、受け取った相手方は送信基に受信確認パケットを返す
  • データが相手に届かないか送信エラーが発生した場合、それを検知してデータの再送を行う
  • 送信したパケットと受信側で受け取るときの順番が異なった場合、順序を入れ替える
  • データが重複して送られた場合、除去を行う

これらは、データがちゃんと相手に届いたか確認するための機能です。

クライアントからサーバにTCP接続要求

3ウェイハンドシェイクを行って、クライアントとサーバ間でSYN(synchronize)とACK(ackowledge)を 投げ合うことでコネクションが確立される。

f:id:o21o21:20180321205945p:plain

TCPコネクションのクローズは、切断要求としてFIN_ACKパケットをサーバに送信。 そうするとサーバからACKパケットが返ってきたのち、FIN_ACKパケットも切断要求として送られてきます。 最後にこちら側からACKパケットを送り返してコネクションがクローズされます。

FIN(= finish),URG(=urgent),PSH(=push),RST(=reset)

TCPヘッダー内

f:id:o21o21:20180321212207p:plain

UDP

UDP(User Datagram Protocol)は、(TCP/IP参照モデルの)トランスポート層コネクションレスプロトコルDNSNTPなどといった応答性の速いサービス、 音声通話や動画などの一部の情報が欠けても問題ないアプリケーションなどで用いられる。

TCPのように相互間のある通信ではなく、一方的に送りつけるようなコネクションです。 低品質だが高速なのがUDPの特徴といっていいでしょう。

IP

IP(Internet Protocol)は、(TCP/IP参照モデルの)インターネット層のプロトコル。 ご存知、「IPアドレス」のIPはこのことですね。

IPv4では、ネットワーク部とホスト部にわけられます。 IPv6では、プレフィックスとインターフェースIDでわけられます。

より詳しく知りたい方はこちらを参考にしてみたらいいかと思います。

  • Subnet mask

Subnet mask( サブネットマスク)は、ネットワーク部とホスト部を区分します。 簡単にいうとネットワークの範囲を知るためのものです。

例えば、192.168.0.1というIPがあったとして、これだけではネットワークの範囲がわかりませんが、 192.168.0.1/24 こうした記述ならわかります。 これはつまり、192.168.0.1/255.255.255.0 = 192.168.0.0〜192.168.0.255 = 256(性格には254)通りのIPが定義できるという意味です。

24という数字は、ホストアドレス長(=24bit)を表している。 

ICMP

ICMP(Internet Control Message Protcol)は、TCP/IPが動作する上で補助的な役割を果たすためのプロトコル(トランスポート層)。 IPの制御メッセージやエラー通知を転送するのに用いられます。

コマンドととして有名なのは、pingなどのEchoReplyや、ルータ間での1回のデータ転送で送信可能なIPパケットの最大値(MTU) の調整などです。

ルータを超えて他のネットワークとの通信をするので、IPよりは上でTCPUDPよりは下の位置付け。

Well known port

Well known portとは特定のプロトコルで使用することが予約されているポート番号のことです。 (例: HTTP=TCP80番ポート、DNS=UDP53番ポートなど) TCP/UDP共に0〜1023ポートです。

Ephemeral port

Ephemeral port(エフェメラルポート、別名ダイナミックポート)とは、OSが空いているポートの中から ランダムに割り当てられるもので、OSによって違うのですが、1024番以降だったり、32768〜61000の範囲だったりする。

ポートフィルタリング

FW(ファイアーウォール)には、ポートフィルタリングと呼ばれる特定のポートの通信のみ許可したり拒否したりする機能があります。 ステートフルインスペクションという機能で、クライアントからサーバに向かう通信をしたあと、 サーバ側からクライアントに向けての通信(待ち受けるポート)を気にしなくても、この機能が勝手に予測し自動的に通過させてくれます。

参考

【AWS】EMR とDynamoDB間のキャパシティについて

とある業務でとても悩んでいたことがあります。。。

簡単に説明すると、AWSのサービスEMRを使用してDynamoDBのテーブル、レコードへ更新処理を行っていました。 大量の更新があったので、DynamoDBの書込キャパシティ(WCU)を上げて、処理に耐えられるように設定。

いざ更新をかけたときにメトリックスを監視していると、ある一定の値で一定に。

「あれーーーーー....」

秒間ターゲット消費率が20%ほどで一定になって、想定していた時間で終わらない。 結果的には待っていると無事に処理が完了して更新も問題なかった。

ただ、「なんでキャパシティ上がらないねん!!」と、疑問が残って気持ち悪いかんじに。

とりあえず順をおってみていきましょうか。

まずEMRとは?

https://zdnet2.cbsistatic.com/hub/i/r/2014/08/26/d64dd59d-2cf1-11e4-9e6a-00505685119a/resize/1170x878/800edfc6f6eae338a310a2d0f51b5d09/thumb.png

EMR (Amazon Elastic MapReduce)

大量のデータを迅速、容易に、かつコスト効果よく処理するためのウェブサービスです。 ログの分析、ウェブインデックス、データウェアハウジング、機械学習、財務分析、科学シミュレーション、 生物情報科学研究を含む、ビッグデータを確実かつ安全に処理します。

仕組み

Hadoopクラスターを実行するために使用できるサービスです。 Hadoopクラスターとはサーバーセットであり、このサーバーセットは連動して、サーバー間で処理およびデータを分散することにより計算タスクを実行する。 タスクの内容は、データの分析、データの格納、またはデータの移動と変換などが考えられる。 また、起動するとき、EC2によって提供される仮想サーバーでクラスターを実行する。

そもそもHadoopとは

巨大なデータをバッチ処理するための並列分散処理基盤である。 並列分散処理とは、その名の通り、1つの処理を分割して同時に処理を行うことである(数千台のサーバーを利用することが可能)。

そして、Hadoopとかググってると絶対でてくるこれ。

HDFS (Hadoop Distributed File System)

分散ファイルシステムのことである(複数のサーバーにファイルを分割して保持することで、巨大なファイルも扱える)。 

"NameNode(マスターノード)"と"DataNode(スレーブノード)"の二つの構成要素から成る(= マスター・スレイブ構成)。 NameNodeは分散ファイルシステムのメタ情報を管理し、DataNodeはデータの実体を保存する。 ファイルを格納する場合、そのファイルを一定サイズで分割したデータを"ブロック"としてDataNodeで保存します。 DataNodeは故障に備え、ブロックは、複数のDataNodeにレプリカ(defaultで3つ)を保存する。 また、HDFSは保存しているファイルに対して追記のみ利用することができます。ファイルを更新して保存したい場合、 ローカル環境でファイルを更新したあと、更新したファイルをHDFSに保存して上書きすることになります。

MapReduce

分散閭里フレームワークである(= マスター・スレイブ構成)。 マスターノードである"JobTracker"とスレーブノードである"TaskTracker"で構成されている。 JobTrackerは、MapReduceジョブの管理やTaskTrackerへのタスクの割り当て、 TaskTrackerのリソース管理を役割としている。 TaskTrackerは、タスクの実行を役割としている。 (mapとreduceという処理を組み合わせて処理を行う) ローカリティと呼ばれ、JobTrackerがTaskTrackerにタスクを割り当てる際には、 そのTaskTrackerが動作しているサーバと同居しているDataNodeが管理しているデータを極力利用するように割り当てる(= サーバ間の通信量を極力抑える)。

Hive

Hadoop上にDWH(データウェアハウス)を構築するための基盤ソフトである。 HiveQLというSQL風の言語でMapReduceジョブに変換しHadoop上のデータを操作できる。

EMRへSSHして、$ hiveって打つとhiveプロンプトが立ち上がる。 非常に簡単です!

EMRで作業する前、ローカル環境にHadoop環境をつくってみましたが、(EMRクラスターは結構ちゃんとやろうとすると高額...) 「面倒くさい!」です。

いろんなツールやらなんやらをインストールしなければならないからです。

わたしの場合は、CentOS+Vagrantで仮想環境内で作りました。 Dockerで簡単に環境を作成できるものもありましたが、サポートがもう終了していました。

ただ、仕組みがほんの少しわかってよかったなー程度でした。

そして、HadoopやHiveの記事が非常に少ないです。。 日本語の記事はもっと少ない。

仮想環境でググった記事をもとに色々試してみましたが、まずコマンドがサポート終了していたりしました。

まあ、そんなかんじで序盤は手こずりながら試行錯誤で業務遂行のため計画を練りました。

そしていざ更新処理へ。

EMR内でDynamoDBの対象テーブルをマッピングさせて、テーブルを作成していました。 DynamoDBに負荷がかかるので、書込キャパシティを上げます。

Hiveプロンプトで以下を設定。

hive > SET hive.execution.engine=tez;
hive > SET dynamodb.throughput.write.percent=0.9

これでOKと実行したわけです。

ですが、上記で説明した通り、想定通りのターゲット消費率が....

色々と調査したところ原因を掴みました。

(そんなんきちんとAWSのドキュメント読んだりEMRとかの内部をあらかじめ理解しておけばいいやん!なんて言わないでく.....)

まず以下を設定していました。

DynamoDB

  • 最小WCU: 3,000
  • 最大WCU: 10,000
  • ターゲット消費率: 70%

プロビジョンドスループット

  • dynamodb.throughput.read.percent=0.9
  • dynamodb.throughput.write.percent=0.9
  • hive.execution.engine=tez;

DynamoDBの設定を問題ありません。書込には3,000キャパシティで70%を消費し、 dynamodb.throughput.write.percent=0.9が想定なので、2700が使用可能なWCUです。

問題なのは、ジョブにおける各タスクへのキャパシティ割り当てでした。

EMRはHDFSMapReduceがコアなコンポーネントとして用意されています。 その他にもさまざまなコンポーネントが存在していて、 例えば、EMRでDynamoDBをマッピングしてテーブル操作を扱うためには、DynamoDB connectorというコンポーネントが必要なようです。

これはEMR内にDynamoDBのテーブルをマッピングさせてCREATE TABLEしたときに、

STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler'

こんなかんじでDynamoDB connectorを使用していました。

タスク自体は想定するMapタスクの数字を算出していましたが、実際に書込を行っていたタスクはその数字よりも低かったのです。

各タスクへのキャパシティ × タスク数 = 毎秒処理するレコード数

なるほどでした。

これらを求めるには、EMRから作成されるログファイルの中身を調査してみるといいでしょう。 実行している時間をメモっておけば心配ありません。 見慣れないログファイルかもしれませんが、よく見ると丁寧に情報がかいてありました。

そして、実行エンジンにはtezではなく、mr(MapReduce)を使用すること。

hive > SET hive.execution.engine=mr;

まとめる

想定通り最大限ターゲット消費率を使用するには、 MapタスクDynamoDBStorageHandler 内で取得される Map 数同等にしなければならない。

参考

【SQL】DBのインデックスについて

今回は第八章「SQLにおける順序」についてですが、 このブログでは、今までの記事で賄えることと、機能も進化している点があるかと思いましたので割愛させて頂きます。

本では主に今までのノウハウを用いて、ナンバリングなどを解説しています。

抑えておくこととしては、以下を意識できていればよいかと思います。

SQLは伝統的に順序をもった数を扱う機能を持っていませんでした。 テーブルの行が順序を持たないと定義されていたことと、 業務的に意味を持たない連番はエンティティの属性とはみなされなかったことがあります。

しかし、近年のSQLでは連番などを扱うための機能が追加されてきているそうです。 だんだんと伝統的な集合指向に手続き型の考えをミックスした言語に変わっているということです。

そして第九章「更新とデータモデル」です。

こちらも今までの記事で賄える部分が多いはずです。 なので、こちらもまとめのみです。

今までと同様、実行計画を確認しながら効率のよいUPDATE文を組み立てることが重要です。 例えば、行列複数列更新するなら、複数列をリスト化して一度に更新するという方法が考えられます。

  • SQLにおける更新の効率化の鍵は、行式、サブクエリ、CASE式、MERGE文
  • モデル変更の方がスムーズに解決できる場合もあるが、苦労を伴う

何れにせよ、全ての問題を必ずしもコーディングで解決する必要はないということを意識しておくこと。

続いて第十章、最終章です。

こちらは、「インデックスについて」です。

インデックスは、その構造に基いて分類すると3つにわけられます。

  • B-treeインデックス
  • ビットマップインデックス
  • ハッシュインデックス

B-tree

treeという単語がある通り、データを木構造で保持するタイプのインデックスです。 RDBにおいて主役であるといってもいいかもしれません。

以下のリンクにイメージが載っています。 B-trreもB+treeも本質は変わりないです。

https://upload.wikimedia.org/wikipedia/commons/9/92/B-tree-definition.png

では、どのような列に対してインデックスを作成するべきなのでしょうか?

列のカーディナリティと選択率

カーディナリティとは、値のばらつき具合を示す概念のことです。 最も高いのは、全ての行について値が異なる一意キーの列。 最も低いのは、値が1種類しか存在しない列です。 行が複数でも考え方は同じです。

選択率とは、特定の列の値を指定したときに行をテーブル全体の母体集合から、どの程度絞りこめるのかを示す概念です。

なので、

  • 値がよくばらついてること (カーディナリティが高い)
  • 少ない行に絞りこめること (選択率が低いこと)

これらで5%未満の絞りこめる条件ならばインデックスを作成価値があるかもしれないということです。 (例: 100レコード、キーpkey=1で指定すれば1件に絞りこめる = 1/100 = 0.01 = 1%)

インデックスが使用できない場合

場合によってはインデックスで逆に悪影響を及ぼすことがあります。

この場合の解決策としては、アプリケーション設計で対処することデータマートなどです。

ビットマップインデックス

データをビットグラフに変換して保持するタイプのインデックス。

ハッシュインデックス

キーをハッシュ分散することで、等値検索を高速化することを目的にしたインデックス。

column指向なのかrow指向なのか

DBによってカラム指向(列)かロー指向(行)なのか認識しておく必要があります。 インデックスオンリースキャンを利用する際も行指向ならば結局フルスキャンするしかないからです。

まとめ

B+treeは基本でいろんなRDBに採用されていることがわかりました。 うまく高速化するのはカーディナリティと選択率次第ということも覚えておきましょう。 選択率が高かった場合は、インデックスオンリースキャンが有効でした。

この記事で最終章が終わりました。 非常に良書で、キャリアの長いエンジニア向けではありませんが、 若手でDBに触れているけど、なんとなくで操作している、なんて方にはピッタリな技術書かと思います。

AWSGCPといったクラウドサービスが当たり前になってきましたが、 SQLやDBの基礎を固めていくことで、されらのサービスを利用した際(ドキュメントと読むなど)に なんとなく用語の意味がわかったり、理解度が増すのではないでしょうか。

  • 前回の記事

o21o21.hatenablog.jp

【SQL】サブクエリの基礎

前回の続きで第七章の主要点をまとめていきたいと思います。 (※具体的なテーブル表など割愛させてもらうことが多いです)

今回は「サブクエリ」についてです。

サブクエリとは、SQLの中で作成される一時的なテーブルということを抑えましょう。 業務中では、困るとよくサブクエリを使用したりする癖がわたしはありますが、本当に効率的なのかこの章では考えてみます。

先に前提をはっきり意識するために以下を覚えておきます。

  • テーブル 永続的且つデータを保持する。

  • VIEW(ビュー) 永続的だがデータは保持しない。アクセスのたびにSELECT文が実行される。

  • サブクエリ 非永続的で生存期間(スコープ)がSQL文の実行中に限られる。

サブクエリの問題

サブクエリはデータを保持しないことを意識する

実態的なデータを保持しないということで、当たり前ですがSELECT実行にかかるコストが上乗せされます。 このサブクエリが複雑なほどコストは落ちることになります。

面倒になってくるとサブクエリが多少複雑でも欲しい結果が得られれば「これでいいや!」ってよくなりますね笑

また、オプティマイザがクエリを解析するために必要な情報がサブクエリの結果からは得られません。

サブクエリが有効なときはどういうときなのか、ここからは考えてみます。

サブクエリが有効なとき

テーブル Receiptsを想定してみます。 このテーブルは顧客の購入明細を記録するテーブルで、連番(seq)列は顧客の古い購入ほど小さな値が振られています。 ここで最小の連番(seq)の金額(price)を求めることを考えてみると、ある顧客に対して一番古い購入履歴を見つけることと同義です。

このSQL文を考えるとき、テーブルへのアクセスを1回にします。I/Oを考慮します。

それと、ウィンドウ関数、ROW_NUMBERを使います。

ROW_NUMBERで行に連番を振り、常に最小値を1にすることで、seq列の最小値が不確定という問題を対処します。

SELECT cust_id, seq, price
FROM ( SELECT cust_id, seq, price,
                            ROW_NUMBER () OVER ( PARTITION BY cust_id
                                                                       ORDER BY seq) AS row_seq
              FROM Receipts ) WORK
WHERE WORK.row_seq = 1;

こうしたクエリでないとテーブルへのアクセスが2回になったり、クエリ自体が読みにくくなってしまいます。

また、テーブル Companiesテーブルとテーブル Shopsテーブルを想定します。 Companiesには、co_cd(会社コード)とdistrict(地域)があって、 Shopsには、co_cd(会社コード)、shop_id(事業所ID),emp_nbr(従業員数)、main_flg(主要事業所フラグ)があります。

1:Nの親子関係があるテーブルだと思って下さい。

ここから会社ごとの主要事業所の従業員数を含む結果(会社の地域を含めた)を得たいとします。

この結果を求めるには2通りのSQLが考えられます。

  • 結合を行ってから集約を行う
  • 集約を行ってから結合を行う

INNER JOINでShopsを指定するのか、INNER JOINでサブクエリを組んでそれを仮テーブルとして集約を先に行うかです。

この2つのクエリの結果は同値です。 そして文的にも複雑でないので問題ありません。 ですが、「どっちのほうがいいの?」と疑問におもってしまいます。

答えとしては、性能的に違いが出て来るケースがあり、パフォーマンスに影響してくるということです。

ポイントは、対象行数です。

前者は、 * 会社テーブル : 4行 * 事業所テーブル: 10行

後者は、 * 会社テーブル : 4行 * 事業所テーブル(仮テーブル名) : 4行

後者のテーブルでは、会社コードで集約されると4行になります。

先に集約してから結合対象の行数を絞ってあげるとI/Oコストを削減できるというわけです。 これはデータの量が増えるほど期待できます。

まとめ

サブクエリは欲しい結果の対して便利な道具であるが、パフォーマンスをかえって悪化させてしまうかもしれない。 I/Oを考え、困難を分割することは悪くないが、ウィンドウ関数や結合対象のテーブルを事前に絞ることをわすれずにすれば、 I/Oコスト的にも、SQL文的にも改善できる点が見つかるかもしれません。

  • 前回の記事

o21o21.hatenablog.jp

【SQL】RDBの結合について

前回の続きで第六章の主要点をまとめていきたいと思います。 (※具体的なテーブル表など割愛させてもらうことが多いです)

今回は「結合(JOIN)」についてです。

正規化というプロセスを踏むために、必然的にRDBではテーブルが増えることになります。 散在するデータを得るため、さまざまな種類の結合を利用するということになります。

結合の際にもパフォーマンスは重要なポイントになってきます。

Nested Loops」というアルゴリズムを覚えておきましょう。

DBMS内でどういったアルゴリズムが使用されているか意識できるようになれば、応用も熟していけるでしょう。

それで順番にみていきましょう。

結合の種類

  • クロス結合
  • 内部結合
  • 外部結合
  • 自己結合
  • 等値結合 / 非等値結合
  • 自然結合

ここでは主に上から3つをみていきます。

クロス結合(cross join)

名前はなんとなく聞いたことがあるかもしれませんが、クロス結合は業務ではほとんど使用したことがないかもしれません。

クロス結合は、数学的には直積やデカルト積と呼ばれる演算です。 2つのテーブルのレコードから、可能な全ての組み合わせを網羅する演算になります。

なので、このような2つのテーブルでは、「6×4 = 24」24行が結果として出力されます。

  • Employees(社員)テーブル
emp_id emp_name dept_id
001 石田 10
002 小笠原 11
003 夏目 11
004 米田 12
005 山田 12
006 岩瀬 12
  • Departments(部署)テーブル
emp_id emp_name
10 総務
11 人事
12 開発
13 営業
SELECT * FROM Employees
CROSS JOIN Departments;

このクエリを実行するとわかりますが、この結果を求めたいという時はほぼないでしょうし、 非常にコストのかかる演算になってしまいます。

ただし、この結合をわかっていれば内部結合や外部結合が理解しやすくなるでしょう。

内部結合 (inner join)

さきほどの2つのテーブルにたいして内部結合を行うにはこうします。

SELECT E.emp_id, E.emp_name, E.dept_id, D.dept_name
FROM Employees E 
INNER JOIN Departments D
ON E.dept_id = D.dept_id;

内部とは「直積の部分集合」という意味です。 内部結合ではサブクエリで代替可能ですが、基本的に結合で記述できる場合は結合を選択すべきです。

外部結合 (outer join)

外部とは「直積の部分集合にならない」という意味です。 常に部分集合にならないというわけではありません。

外部結合には3種類あります。

  • 左外部結合
  • 右外部結合
  • 完全外部結合

マスタとなるテーブルを左に書くなら左外部結合、右に書くなら右外部結合です。 マスタにのみあるキーがあった場合は、出力されることになります。

f:id:o21o21:20180318140855p:plain

自己結合 (self join)

自己結合は、演算の対象になにを使うかという点が問題になってきます。

一般的に同じテーブルに別名をつけて、 (例: Employeesというテーブルに対してSQL内で、AS E1, AS E2 などとする) それらをあたかも別テーブルのようにして扱います。

アルゴリズム

オプティマイザがどのアルゴリズムを使用するかは、データサイズや結合キーの分散といった要因にも依存してきますが、 最も頻繁に確認できるのが「Nested Loops」でしょう。

その他にも、

  • Hash
  • Sort Merge

などがあります。 これらのアルゴリズムは多くのDBMSでサポートされているかと思います。 確認してみたら、「そんなアルゴリズムは使用されていない!」って方も、派生系などがありますので、よくドキュメントを参考にしてみてください。 要は、基本的なところでは似ているかと思います。

Nested Loops

結合は常に1度につき2つのテーブルしか結合しません。

tabale_Aとtable_Bとの結合だとして、

  1. 結合対象となるtable_A(駆動表or外部表)を1行ずつループしながらスキャンする。
  2. table_B(内部表)を1行ずつスキャンして、結合条件に合致したものを返却する。

この繰り返しです。

それぞれのテーブルの行数をR(A), R(B)とします。 アクセスされる行数は、R(A) × R(B)となります。 これはNested Loopsの実行時間はこの行数に比例するということになります。

また、Hashなどと比べて、1ステップで処理する行数が少ないためあまりメモリを消費しません。

さて一見するとこれならどちらでもいいではないか(R(A) × R(B)R(B) × R(A))と思われますが、そんなことはありません。 駆動表が小さければNested Loopsの性能が良くなりますが、内部表の結合キーの列にインデックスが存在することという前提があります。 内部表のインデックスをたどることでループすることなく1行を特定できます。 この場合のアクセス行数は、R(A) × 2 になります。

駆動表に小さなNested Loops + 内部表の結合キーにインデックスが基本的なものということを覚えておきましょう。

(= 内部表でヒット件数が多いとパフォーマンスは下がる)

Hash

ハッシュ結合は、まず小さいテーブルをスキャンし、結合キーに対してハッシュ関数を適用することでハッシュ値に変換します。 その次に、もう一方の大きなテーブルをスキャンして、結合キーがそのハッシュ値に存在するかどうかを調べる、という方法で結合を行います。

なのでハッシュテーブルをワーキングメモリに作ります。ワーキングメモリに収まらないと遅延が発生してしまいます。 ハッシュテーブルを作るのでメモリを消費します。出力となるハッシュ値は順序性を保存しません。

ハッシュ結合では両方のテーブルのレコードを全件読込必要があります。

Sort Merge

MergeとかMerge JOINと呼ばれることが多い気がします。 SOrt Mergeは、結合対象のテーブルをそれぞれ結合キーでソートを行い、一致する結合キーを見つけたらそれを結果セットに含めるというものです。

テーブルのソートに多くの時間とリソースを要する可能性があります。テーブルソートをスキップできるケースに考慮が値します。。 なので、Nested Loopsなどがまず優先的に選択肢になると考えておけばよいでしょう。

三角結合でクロス結合?

三角結合とは、JOINを2つ1つのクエリの中に記述するものが考えられます。 それによって、テーブルAとテーブルB、テーブルAとテーブルCの間だけで結合条件を成り立つものです。 テーブルBとテーブルC間には結合条件が存在しません。

こうした時の実行計画でまれにクロス結合が使用されている場合があります。 理由はおくまで推測になるのですが、テーブルBとテーブルCのテーブルサイズが非常に小さいと評価される場合です。 この2つのテーブルサイズが小さければ、テーブルAに2回あたりにいくよりも先にBとCを結合させておくことで テーブルAへの結合を1回におさめることができるからです。

こうした結合を回避させたい場合には、テーブルBとテーブルCの間に結合条件を加えることです。

まとめ

ここまで色々なSQLを試していて、「意図した結果が得られないな〜」なんてことがあるかと思います。 そういうときは、第一章でやった統計情報を更新しましょう。

結合において、実行計画を考慮する際は、変動がおきやすいということを覚えておきましょう。 アルゴリズムが複数あるためです。きちんと考慮しなければならない場合は、一度結合から離れて考えてみるべきです。

  • 前回の記事

o21o21.hatenablog.jp

Alexaでお金を稼ぐことはできるのか?

スマートスピーカーといわれる、音声操作に対応したデバイスがここ数年話題になっている。

この記事では、Amazonが提供しているAmazon Alexaについて、 マネタイズができるのか、ということを調査してみた。

※この記事の情報は、12月2017年ころのものを参考にしています。

Alexaとは

Amazon EchoAmazon Echo Dot,Amazon Echo Show,また他のサードパーティのAlexaが使えるデバイスの中核となえる音声サービスのことです。

よりパーソナライズされた操作性を実現するにあたって、Alexa Skills Kit(ASK)Alexa Voice Serviceが存在します。

Alexa Skills Kit(ASK)とは

設計者や開発者、企業は、ASKを使って魅力的なスキルを開発し、数多くのユーザーにアピールすることができる。セルフサービスの一連のAPI、ツール、ドキュメント、コードサンプルなどが無料で公開されている。 それらを利用してスキルを作り出すことができます。

Alexa Voice Service(AVS)

マイクとスピーカーを搭載したインターネットに接続するあらゆる端末にAVSを使用して音声制御機構を追加できます。

スキルとは

スキルには主に4つのタイプに分類できます。

  • スマートホームスキル 自宅の家電などをAlexaに学ばせることで、ユーザーの生活にハンズフリーの操作性を実現します。

  • カスタムスキル 既存のサービスやアイディアを基に独自の対話モデルを構築し、様座な場面で活用できます。

  • ゲームとトリビアのスキル インタラクティブアドベンチャーゲームトリビアスキルで仮想現実の世界を提供できます。

  • フラッシュブリーフィングスキル 事前に録音されたオーディオクリップなどによって、最新のコンテンツをユーザーに届けることができます。

このようなスキルを開発して、企業はサービスを提供したり、様々な情報を音声で提供したりする。また、このスキルはプログラミングの知識があれば誰でも開発ができるようになっている。

そして、まだ日本国内ではリリースされていないが、スキルの開発で報酬を得るということもできるようになるらしい。 その他、企業目線で音声でどういったことが収益につながるか、以下にメモってみる。

Alexa Developer Rewards

Alexa Developer Rewardsとは、Alexa Skillの報酬プログラムのこと。 Amazonが以下のカテゴリで最も高いカスタマーエンゲージメントを獲得できたスキルに対し、 毎月報酬を支払うというものである。

  • Education & Reference
  • Food & Drink
  • Games, Trivia & Accessories
  • Health & Fitness
  • Lifestyle
  • Music & Audio
  • Productivity

カスタマーエンゲージメントの詳細は提示されていないが、スキルの使用者数や使用時間、 レーティングなどから総合的に判断されるのではないかということ。 現在対象としている国は、アメリカやイギリス、ドイツのみ。

Skill内、追加コンテンツ販売

販売方式は買い切り、サブスクリプションが可能。

: クイズ番組のスキル $1.99を毎月払うことで、毎日提供されるクイズの数が2倍に。 よくよくはAmazon Primeに対してのディスカウント設定も可能だとか。

既存のビジネスとの連携

すでにあるビジネス、サービスとアカウントリンクなどによって連携し収益化することが考えられる。 ※アカウントリンクとは、Alexaに設定されているユーザーと、スキルのシステムのユーザーアカウントを結びつけること。

Amazon Pay

Amazon Skill内での支払いにAmazon Payが使用できるようになった。 勿論、Amazonアカウントのみでの支払い。Alexaと連携すれば音声での買い物も楽になりそう。 ※こちらも日本はまだ

広告事業について

広告事業については、まだ本国アメリカでも公にされていない。 15〜45秒で商品に紹介をユーザーの購買履歴をもとにして(勿論音声で)行うのではないかと思われる。 広告といえど、ささやかに提案するような言い回しになるらしい。笑

※02.10.2018に記事がでました。 https://news.yahoo.co.jp/byline/kokuboshigenobu/20180210-00081480/

スキルの受託

ASKやAVSが提供されているので、開発者はスムーズに開発を始められる。 とくにAlexaを利用する業界が絞られているわけではないので、きちんと台本やら発話のサンプルを 用意しておけば開発で困ることはないだろう。 経験としておすすめは、Node.jsで開発することかな〜

(おまけ) Alexa for Business

Alexaを使って、ビオジネス及び組織の仕事場で業務の効率化をはかること、ユーザーやスキルの一元管理をするためのAmazonが提供しているサービス。 料金 共有デバイス: 7USD/デバイス 登録されたユーザー: 3USD/ユーザー ※2018.1.4現在バージニア北部リージョンで使用可能

例えば以下のようなことができます。

  • 会議室からミーティングに参加 Alexaは、ビデオ会議装置の電源をつけ、電話会議用電話番号にダイヤルしミーティングを開始。

  • 空いている会議室を探したり、用品のオーダー、来客の応対など。

  • カレンダーをチェックし、ミーティングの手助け、ToDoリストを管理したりリマインダーをセットできる。

簡単にいうと、企業向けで、来客してきたお客様の対応とか、 (今でも受付で電話するところがおおいかな? でも、一人で受付で「アレクサ!」とか言えるのか?w) 家にいてもどこにいてもAlexaがあればミーティングに参加(社畜フラグww)できたり、 音声で開いている会議室とか確認予約できるようです。

まとめ

  • ユーザーに好まれる優良スキルを開発すること
  • 既存ビジネスとの連携をして売り上げる(既存ビジネスに課金コンテンツがあれば)
  • 高単価で受託をたくさんこなす(デプロイや開発環境効率化をまず整えたほうが良いかも〜)
  • Skill内追加コンテンツが日本に導入されるまで待って、Skill内課金で売り上げる

サクッとしたメモでした。

【本】ニューエリート グーグル流・新しい価値を生み出し世界を変える人たち

先々週くらいに書店で目についた本があります。 その時は購入しなかったのですが、気になったので翌日購入しました。

「ニューエリート グーグル流・新しい価値を生み出し世界を変える人たち」

ニューエリート グーグル流・新しい価値を生み出し世界を変える人たち

ニューエリート グーグル流・新しい価値を生み出し世界を変える人たち

こうしたカテゴリの本は久しぶりに読むですが、共感できることが非常に多くあっという間に読み終えました。

率直な感想としては、「はやくこの本を読むべきだ!」と思いました。

今だからこそ、活きてくる内容が沢山書かれていました。 と限定しているのは内容的にも、IT企業に務めている方はご存知の通り、技術の発展が高速で 毎日新たなツールやパッケージ、サービスが生まれてくるので、例えば数年後に読んでも感じ方が違うのではないか? と、思ったからです。

まず、著者について。 ピョートル・フェリクス・グジバチさん

ポーランド生まれ。ドイツ、オランダ、アメリカで暮らした後、2000年に来日。2002年よりベルリッツにてグローバルビジネスソリューション部門アジアパシフィック責任者を経て、2006年よりモルガン・スタンレーにてラーニング&ディベロップメントヴァイスプレジデント、2011年よりグーグルにて、アジアパシフィックでのピープルディベロップメント、さらに2014年からは、グローバルでのラーニング・ストラテジーに携わり、人材育成と組織開発、リーダーシップ開発などの分野で活躍。現在は、独立して2社を経営。日本在住17年。ダイビングと合気道を行う。

んー すごい。

以前からお名前は存じていましたが、実際本を読むのは初めてでした。 日本に在住されているということで、目線も日本人向けでした。

この本の概要としては、こんなかんじ。

  • 未来は予言できない。しかし新しい仕事を作ることは、今できる
  • 会社に合わせて生きるくらいなら、社外に道を切り開け
  • アフターファイブに勉強するより、仕事に学びを絡めよう
  • その道のプロに会うためにお金を使うのが、自分がプロになる近道
  • 決断は直感で。早く動いて結果を出す
  • 日本人にはフィードバックが圧倒的に足りない
  • 会議・チーム作りはアウトプットから逆算する
  • チームメンバーは固定させない
  • イノベーションを生み出すチームの条件
  • ラソンではなくスプリントの発想で生きる
  • 人材を活かす企業は「従業員の自己実現のために会社がある」と考える
  • クリエイティブな人材を見分ける前にやるべきこと

現在、企業に在籍している身において、将来的にどう立ち回るべき(会社内とかでなくもっと大局的に)か また、企業のあり方も書いてありました。

わたしはまだ若いですが、エンジニアとして3回ほど転職を繰り返しました。 大学を卒業してからは、(望んでいたのか..望まずしてなのか...)個人事業主という形態で、ベンチャー企業に飛び込みました。 プログラミング自体ちゃんと学んだことはなかったのですが...

それからというもの転職を繰り返して契約、派遣、正社員と2年ほどで一通りの雇用形態でお仕事させてもらってました。

全て直観で行動していたかと思いますが、全て無駄ではなかったし、早く行動して正解だったと思っています。 退職するときの先輩や上司などの顔色を伺う時間がもったいなかった。。(申し訳ないですが...) それ以上にほかの場所で学びたいものがあったので、それに向けて動いていました。

おかげさまで短期間のあいだに仕組みから学ぶことを得ました。沢山の時間をつかって、プログラミングに関して学ぶことを惜しまず投資しました。 

と、他にも色々あったのですが、とにかくそうしているうちにGoogleAmazonシリコンバレーで切磋琢磨している企業さんの 働き方やサービス展開のスピードに衝撃を受けたりしてました。

また、Googleの掲げている理念や著者の発言が非常に国際的で大局をみていることにいつも感化させられます。

以下引用です。

これからの時代をリードする人には、もっと違う定義づけができるはずです。重要なのは、「今どこにいるか」という地位よりも、元いた場所と今いる場所に差があるということ。つまり、僕の成功の定義は「持続的に成長していること」です。 たとえば、会社員だった人が努力の末に起業の夢を実現したら、それがどれだけささやかな事業であっても、見上げるような成功です。小さな会社でも、転職してやりたかった仕事に就けたのなら、やっぱり成功です。 一定期間で区切った成長度合いで比較すれば、特に成功者とみなされていない人の中にも、実は成功者が存在します。 むしろ、彼らが成功者としてみなされる時代が遠からずやってくるはずです。こうした人を、僕はニューエリートと定義しています。

消費者は何にお金を投じるようになるか

アフターファイブに勉強するより、仕事に学びを絡めよう

決断の速さが結果を大きく左右する

日本人にはフィードバックが圧倒的に足りない

チームメンバーは固定させない

アウトプットに不要なメンバーは会議に呼ばない

ダメなチームの原因は、上司の褒め方にある

4つのエネルギーレベルを管理する

あなたはストームトルーパーになりたいか?

幸せに働き続けるために、日本の職場に足りないもの

もしこのブログを読んで頂いて、関心が湧いたら是非読んで欲しいのであんまり中身は書きません。

なにげないことかもしれませんが、この本を手にとってみると、新たな気付きと自分への後押しになってくれる気がします。