オンライン外国為替取引

ファンクションインデックス

ファンクションインデックス

複数の関数を整理する

プロジェクトに Cloud Functions を統合すると、多くの独立した関数を収めるようにコードを拡張できます。ただし、1 つのファイルに収めるには関数が多すぎたり、さまざまなチームがさまざまな関数グループをデプロイすると、あるチームが別のチームの関数を上書きしたり、誤って削除したりするおそれがあります。関数の処理とメンテナンスが簡単になるように、Cloud Functions には、コードを整理するさまざまな方法が用意されています。

コードベースで関数を整理する

firebase.json にある関数の構成オブジェクトの codebase プロパティを使用すると、単一リポジトリの monorepo 設定内で、複数のリポジトリまたはサブパッケージにまたがる、関数の大規模なコレクションを管理できます。

codebase プロパティは、Firebase CLI v10.7.1 以降でサポートされています。

複数のリポジトリの管理

codebase プロパティは、複数のリポジトリの管理を簡素化できます。同一の Firebase プロジェクトに関数をデプロイするリポジトリが 2 つあるケースについて考えます。

コードベースのアノテーションがないと、Firebase CLI では、デプロイの時点で、もう一方のリポジトリで定義されている関数を削除するよう求めるメッセージが表示されます。

この問題を解消するには、各プロジェクト リポジトリにある firebase.json の関数の構成セクションで、一意のコードベースのアノテーションを追加します。

コードベースのアノテーションを使用すると、Firebase CLI で、即時リポジトリの外部で定義されている関数の削除を求めるメッセージは表示されなくなります。

複数のソース パッケージの管理(monorepo)

codebase プロパティを使用すると、単一リポジトリにある複数のソース パッケージの管理を簡素化できます。複数のサブパッケージに関数の定義が分散している Firebase プロジェクト ディレクトリがあるケースについて考えます。

  • monorepo を設定しており、さまざまなチームが独自の関数の定義を、隔絶されたパッケージで管理している。
  • 外部依存関係が高く、初期化の実行時間が長い関数があるため、レイテンシの影響を受けやすい他の関数からその関数を分離したい。

このような monrepo の設定を使用できるようにするには、 firebase.json で複数の関数の構成を定義します。

この構成を使用すると、Firebase CLI の 1 つのデプロイ コマンドにより、すべてのパッケージから関数がデプロイされます。

複数のファイルに関数を書き込む

Cloud Functions を初めて始使用する場合は、最初のいくつかの関数を 1 つのファイルにまとめることができます。

index.js

関数の数が多くなると、このような方法では管理が難しくなります。代わりに、各関数のロジックを独自のファイルに配置し、 index.js ファイルをエクスポート用のリストとして使用します。

foo.js

bar.js

index.js

グループ関数

metrics.js

これらの関数は、 index.js ファイルにエクスポートするときにグループ化できます。

index.js

デプロイされると、関数にはグループ名が接頭辞として追加されます(この例では、 metrics-usageStats 、 metrics-nightlyReport )。

関数をデプロイするときに、アクションを 1 つのグループに限定できます。

次のステップ

Cloud Functions の詳細については、以下をご覧ください。

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a ファンクションインデックス registered trademark of Oracle and/or its affiliates.

そのまま使える、Oracleインデックスのキー圧縮ガイドラインとインデックス設計の話

データの繰り返し値を圧縮することでストレージ容量を節約するもので手軽なので利用している方も多いかと思います。
キー圧縮がうまくいくと1回のI/Oで取得できるレコード数が増加する上にデータベースバッファキャッシュも圧縮状態でキャッシュされるのでその点でも効率が上昇します。ストレージ容量とパフォーマンス両面で恩恵がある機能です。
(※I/Oとパフォーマンスの基礎知識は以前公開したデータベースチューニングの記事を参照ください)

キー圧縮の書式

以下書式でインデックスのキー圧縮を行います。
その際に compress 1 のように数値を指定しますが、この数値は先頭から指定された数値分のカラム数だけプリフィックスエントリ(※後ほど説明あり)という領域に保存されることを表します。

キー圧縮設定の決定ガイドライン

このガイドラインはあくまで おおむね適切な設定が可能 なもので、データの分布次第では最適でないケースもある点はご了承ください。 ファンクションインデックス
完璧な設定を期待するならばキー圧縮機能を熟知した担当者がデータ分布を元に判断する必要がありますが、このガイドラインはそこまでの労力をかけずに わりと適切な設定 を決定することを目的としています。

キー圧縮の仕組み

インデックスはツリー構造となっていて枝分かれを表す ブランチブロック とキー値とレコードへのROWIDを保持する リーフブロック で構成されます。今回利用するキー圧縮機能は後者のリーフブロックに作用します。

文字列カラム2つと数値カラム1つに対して作成されたインデックスを例に、まずは キー圧縮を利用しないリーフブロック の論理構造を以下の図に示します。

キー圧縮の構造

キー圧縮が行われない場合のリーフブロックの構造は単純でインデックスの対象である 文字列カラム2つ, 数値カラム1つテーブルのレコードへのROWID の合計4項目がレコードごとに格納されます。

次は同じインデックスをプリフィックスエントリに保存するカラム数を2( compress 2 )として圧縮した状態のリーフブロックの論理構造です。

キー圧縮の構造

キー圧縮を有効にすると プリフィックスエントリサフィックスエントリ に分離されて先頭から指定した数のカラムがプリフィックスエントリに、それ以降のカラムがサフィックスエントリに格納されます。そしてサフィックスエントリからプリフィックスエントリのレコードを参照します。

プリフィックスエントリに格納される値が同一ならば1回だけの記録で済むのでストレージ容量を節約できます。
しかしここで注意点としてプリフィックスエントリは カラムごとに同一の値が登録されるのではなく全てのカラム値がまとめて登録される ということに気をつけましょう。これは重要なのでしっかり意識が必要です。

例えばプリフィックスエントリに2カラム格納する設定( compress 2 )でインデックスを作成します。そのデータの分布として先頭のカラムは同じ値が繰り返されているものの次のカラム値がバラバラだったとすると圧縮効果は得られません。この場合はプリフィックスエントリのカラム数を1( compress 1 )とするのが最適です。

圧縮効果の比較

  • 繰り返しのある文字列カラム(単数)
  • 繰り返しのある数値カラム(単数)
  • 複合インデックス

繰り返しのある文字列カラム(単数)

ファンクションインデックス ファンクションインデックス
ID
000000000000000000000000000001
000000000000000000000000000001
000000000000000000000000000001
000000000000000000000000000001
000000000000000000000000000001
000000000000000000000000000002
000000000000000000000000000002
000000000000000000000000000002
.
000000000000000000000002000000
000000000000000000000002000000

この状態でインデックスのサイズは 472MB となりました。

結果は 208MB ファンクションインデックス となり、56%ほど削減できました。
長い文字列をレコードごとに毎回格納していたのがキー圧縮によって5回に1回の格納で済むようになったのが容量削減の要因です。

繰り返しのある数値カラム(単数)

このテーブルには以下のように 1 ~ 2000000 の数値が5回ずつ繰り返されるレコードを1000万レコード挿入しました。

ID
1
1
1
1
1
2
2
2
.
2000000
2000000

この状態でインデックスのサイズは 184MB となりました。30byte の文字列に対して作成したインデックスよりもこの時点でだいぶ小さめです。

結果は 152MB となり、削減率は17%ほどでした。30byte の文字列のケースより圧縮率は下がっています。
数値は値の保存に必要なバイト数が 30byte の文字列よりも小さいので、圧縮の効果も必然的に低くなります。

圧縮率で数値カラムと文字列カラムを比較すると数値カラムの方が不利です。
しかし一般的に文字列カラムにインデックスを作成するケースは数値カラムと比べると多くないのと、文字列カラムは同一値となるケースがそもそも多くありません。
もし文字列カラムに同一の値が繰り返されている状況があるならば、キー圧縮よりも先にマスタ化や正規化を気にした方が良いかもしれません。

複合インデックス

少し脱線しますが Oracle で任意の行数を得る方法はいろいろあり、最もポピュラーなのは以下の connect by を利用した方法でしょうか。

そこで私がよく使う方法が前述の2行返すテーブル( select 1 from dual union all select 1 from dual )を cross join ファンクションインデックス によるデカルト積で倍々と増やしていく方法です。2の24乗が 16,777,216 で1000万を超えるため、今回は24個結合しています。
確保するメモリが最小で済むので膨大なレコードでもそれに見合う処理時間さえあれば正常に実行可能です。
ただし生成した膨大なレコードに対して実行計画における後続処理でソートしたり別テーブルにハッシュ結合したりすると、その時点で全レコード分のメモリ確保が必要になるので実行に失敗する可能性があります。NESTED LOOP結合などのフィルタ的な処理ならば時間はかかるものの問題ありません。

ファンクションインデックス
カラム 説明 カーディナリティ 値の概要
id 注文ID 最も高い 1 ~ 10,000,000 の連番
customer_id 顧客ID 低い 1 ~ 1,000 ファンクションインデックス のランダム値
order_date 注文日時 高い 2020-01-01 00:00:00 ~ 2020-12-31 23:59:59 のランダム値
shipped出荷フラグ 最も低い 0, 1 ※0は全体の1%
note メモ 最も高い id値の先頭を0埋めして30桁とした文字列

customer_id はカーディナリティが低いので繰り返し値は多め、一方 order_date は秒の精度で記録されているためカーディナリティが高く9割以上のレコードには同一日時がありません。

ファンクションインデックス

ファンクションインデックス ファンクションインデックス
No. カラム1 カラム2 nocompress compress 1 compress 2
No.1 customer_id order_date 256MB 210MB (-18%) 320MB (+25%)
No.2 order_date customer_id 256MB 298MB (+16%)320MB (+25%)
No.3 customer_id shipped 200MB 162MB (-19%) 128MB (-36%)
No.4 trunc(order_date) customer_id 256MB 170MB (-34%) 136MB (-47%)

まずは No.1 の customer_id, order_date に対するインデックスです。customer_id はカーディナリティが低めで同じ値のレコードが多いため、customer_id をプリフィックスエントリに保持するように compress 1 とすると容量が18%ほど削減されました。
続いて compress 2 として order_date もプリフィックスエントリに追加すると、order_date はカーディナリティが高いので customer_id, order_date の両カラムが一致するレコードはほとんどなくなってしまい、結果として元のサイズから25%も容量が増加してしまいました。

No2 は No.1 と同じカラムで順番をひっくり返した(order_date, customer_id)インデックスを作成しました。
逆順ではありますが同一カラムが対象なので nocompress の場合のサイズは同一です。(ただしブランチブロックの配置やリーフブロックでのレコードの並び順は大きく異なるので多少の差が出る場合もあります)
続いてキー圧縮を試すと今回は先頭の order_date のカーディナリティが高いので compress 1 の時点で16%も容量が増加してしまいました。
さらに compress 2 で customer_id もプリフィックスエントリに加えると No.1 と同一の25%増となります。2つのカラムの一致は順番が異なっても変わらないのでほぼ同じサイズになります。

No.3 は No.1 と比較用に2カラム目をカーディナリティの低い shipped カラムに変更してみました。
compress 1 の対象カラムは No.1 も No.3 も同じ customer_id なので当然データ分布は同一、そのためインデックスサイズの削減率もほぼ同じで18 ~ 19%程度となっています。
注目すべきは compress 2 とした場合です。No.1 はカーディナリティの高い order_date だったので容量が増加してしまったのに比べ、No.3 の shipped は値の種類が 0, 1 だけとカーディナリティが低いので -36% となり compress 1 ファンクションインデックス よりさらに容量が削減されています。

No.4 はファンクションインデックスを使って order_date の時刻を 00:00:00 に丸めた状態でインデックスを作成しています。
以下のような任意の1日での絞り込みや日の範囲検索に利用可能です。

では No.4 と No.2 を比べてみます。対象カラムおよび順番は同一ですが、No.2 は order_date に時刻がそのまま入っていて、No.4 は時刻が 00:00:00 に丸められています。
キー圧縮無効では両インデックス共に 256MB で同じサイズになりました。No.4 は時刻情報を丸めているだけでDate型自体の精度や保持に必要なサイズが変化しているわけではないので納得の結果です。
次の compress 1 では大きな差が出ています。order_date をそのままプリフィックエントリに保存した No.2 は元のサイズから 16% も増加したのに対して、時刻を丸めた No.4 は 34% 削減されています。時刻を丸めるとカーディナリティが低くなるのでこれも納得の結果です。 compress 2 で customer_id がプリフィックスエントリに追加されると差がさらに大きくなります。No.2 は order_date だけでも同じ値のレコードが少なかったのに、そこに customer_id が加わるとさらに状況が悪化します。

ガイドラインの解説

絞り込みを目的とした複合インデックスは途中のカラムのカーディナリティを低くしないとそれ以降のカラムでの絞り込みにインデックスが有効に機能しません。
その理由を先ほどの orders テーブルに対する order_date, customer_id の複合インデックスで考えてみます。

order_date の単一値検索(パターンA~C)は全てのケースで最大の適正がありますが、範囲検索(パターンD~F)になると適正なのは order_date のみに対する範囲検索(D)ファンクションインデックス に限定されます。

例えばパターン(E)の「order_date の範囲 かつ customer_id の単一値」の動作を考えると、指定された order_date の範囲すべてを INDEX RANGE SCAN した上で条件に含まれる customer_id のレコードをピックアップすることになるので、customer_id の絞り込みについては効率が良いとは言えません。とはいえ次点の○適正となっているのは INDEX RANGE SCAN でヒットしたレコードに対してそれぞれROWIDでテーブルからデータを取得するよりはインデックス内にデータがあった方が速いためです。しかしこれは以降で解説するカバリングインデックスに近い使い方なので基本的なインデックス設計の範囲を少し逸脱しています。

次に(A)~(C)の order_date の単一値検索ですが、インデックスの適正としては確かに◎なのですが order_date はカーディナリティが高いので customer_id もインデックスに含める必要性はさほどありません。
利用頻度の高いであろう order_date の範囲検索も普通に設計したら前述の通り customer_id はインデックスに追加されないことが多いです。

こればかりは画一的な決定が難しいのでガイドラインでは実際のデータを元として繰り返しが概ね4回より多そうなら全カラムをプリフィックスエントリに保存し、4回未満なら「カラム数 - 1」として最後のカラムをプリフィックスエントリから除外しています。
「カラム数 - 1」なのは上記のユニークインデックスで書かれた理由と同一で、通常のインデックス設計では最後のカラム以外はカーディナリティが低くなることが多い(=データの繰り返しが多い)からです。

ORDER BY狙いのインデックス

細かい点ですが、並び順の指定で order_date だけではユニークにならないので、ここでは id も追加しています。
ユニークになるカラムまで指定しないと同一値だった場合の順番が未定義となるので、システムで利用する場合に問題が発生することがあります。

ここで order_date, id に対する複合ユニークインデックスを作成します。

テーブルフルスキャンとソート処理がなくなって代わりに INDEX FULL SCAN DESCENDING が登場しています。
先ほど作成したインデックスの逆順が今回のSQLで指定されている order_date desc, id desc と一致するので、インデックスを最後の要素から逆順に取得すればソートが不要になるのです。

INDEX FULL SCAN となっていますが COUNT STOPKEY によって100行取得したら処理が中断するので実際にはフルスキャンされません。

ではこの ORDER BY 狙いのインデックスへキー圧縮を適用してみます。

No. カラム1 カラム2 nocompress compress 1 compress 2
No.5 order_date id 264MB 312MB (+18%) ---MB (---%)

ORDER BY 狙いのインデックスは最初のカラムが主な並び順を決定する日付などカーディナリティの高いカラムであることが多く、安易にキー圧縮すると逆効果になります。
今回のケースでは order_date のカーディナリティが高いので compress 1 で 18% もサイズが増加してしまいました。2カラムのユニークインデックスのため compress 2 は設定できません、このインデックスの場合は nocompress が最適です。

さらに複雑なケースでは ORDER BY と絞り込みの両方を狙うこともあって画一的な判断を難しくしています。
例えば検索条件に ファンクションインデックス shipped = 1 を追加して「出荷済みの最新100件」を取得する要件ならば、 shipped, order_date, id 3カラムの複合インデックスを設計することもあり、その場合の最適な圧縮設定は shipped だけをプリフィックスエントリに保持する compress 1 です。

カバリングインデックス

次に order_date にインデックスを作成します。
普通に設計したら大抵の方はこのインデックスを作ると思われます。

すると実行計画は以下のように変化しました。
まずは INDEX RANGE SCAN でインデックスから対象行のROWIDを取得。次にROWIDでテーブルからレコードを取得した上でグループ化するという内容で、これは十分に効果的なインデックスです。

では次は customer_id もインデックスに加えてインデックスを作り直してみます。

ファンクションインデックスを利用したデータ削減手法

最後に少々トリッキーなインデックスを紹介します。
trunc(order_date) でカーディナリティを下げてキー圧縮効率を上昇させる例を紹介しましたが、その応用です。

ID
000000000000000000000000000001
000000000000000000000000000002
000000000000000000000000000003
.
000000000000000000000000030002
000000000000000000000000030003
.
000000000000000000000009999999
000000000000000000000010000000

この時点でテーブルのサイズは 400MB になりました。

次にユニークインデックスを作成すると 456MB でした。
元のテーブルは 400MB でしたが、インデックスは全く同じデータを持つものの B+Tree 構造で容量が多少増加しています。

では擬似的に2カラムに分割したファンクションインデックスを compress 1 で作成します。

ファンクションインデックス

ID SUBSTR(ID, 1, 28) SUBSTR(ID, 29)
000000000000000000000000000001 0000000000000000000000000000 01
000000000000000000000000000002 0000000000000000000000000000 02
000000000000000000000000000003 0000000000000000000000000000 03
. . .
000000000000000000000000030002 0000000000000000000000000300 02
000000000000000000000000030003 0000000000000000000000000300 03
. . .
000000000000000000000009999999 0000000000000000000000099999 99
000000000000000000000010000000 0000000000000000000000100000 00

実際にこのインデックスのサイズは 152MB でした。元のインデックスが 456MB だったことを考えると劇的にサイズが削減されている上に、元テーブルの 400MB と比べても半分未満になりました。
検索時に28文字と2文字に分離が必要など扱いは少し面倒ですが、このファンクションインデックスを利用してカバリングインデックスとして利用するとI/O効率が上昇します。

SELECT で取得する値もファンクションインデックスで分割された2カラムを結合( substr(id, 1, 28) || substr(id, 29) )しているので、元テーブルにはアクセスせずに取得可能です。
元テーブルを完全に再現可能なカバリングインデックスが元テーブルの半分以下のサイズとなるのは面白い現象です。

本稿の内容は元々ラクーングループ内で利用するガイドラインとして用意を始めた資料だったのですが、キー圧縮機能は Oracle を利用するどの環境でも有用なものなので外部公開用に書き直して公開しました。
ぜひ活用されていない方は本ガイドラインを元にキー圧縮機能デビューしてみていただけたらと思います。

パフォーマンスチューニング9つの技 ~「探し」について~
PostgreSQLインサイド

PostgreSQLの「探し」のポイント

SELECT文にORDER BY句を使用する場合には、ORDER BY句に書かれているカラムの順番でインデックスが定義されていれば、SELECT文の実行時にソート処理が省略されます。それは、ソート処理を実行しなくてもインデックスを順番に見ていくことでソートされた結果を取り出すことができるためです。その結果、SELECT文は高速に処理できます。また、LIMIT句がある場合は、LIMITで指定された個数までしかデータにアクセスしないで済むため、さらに効果が見込めます。

ソート処理をインデックススキャンで代用する例(LIMIT句も利用)

検索方式Index Only Scanを活用する

SELECT文で指定されたWHERE句と選択リストに指定されたカラムがすべてインデックスに含まれている場合、および、インデックスの種類がB-treeなどのようにIndex Only Scanをサポートしている場合には、プランナーが実行計画を作成する際に、高速なスキャン方式であるIndex Only Scanを選択します。Index Only Scanは、インデックスデータをアクセスするだけで処理ができ、テーブルデータへのアクセスが不要になるため高速な検索が可能です。ただし、インデックスデータのみで高速に処理させるためには、該当のレコードが存在するページが、すべてのトランザクションから取り出し可能な状態になっている必要があり、その情報は可視性マップ(注1)から取得されます。そのケースに該当する例としては、部署データなどの基本的に変更の殆どないマスターデータのテーブルを検索する場合が挙げられます。以下に、その動作概要を示します。

Index Only Scanによるインデックス活用例

図7 Index Only Scanによるインデックス活用例

  • (1)Index Only Scanによりインデックスを検索する。
  • (2)SELECT文の条件に指定されたレコードの存在するページの可視性マップをチェックする。
  • (3)可視性マップをチェックした結果、ページすべてがトランザクションとして取り出し可能であるかどうか判断する。 ファンクションインデックス ファンクションインデックス ファンクションインデックス
    • 可能である場合は、ページにアクセスせずインデックスのデータを取得する。
    • 可能でない場合は、実際にページをアクセスし、取り出しが可能かどうかを判断した上でデータを取得する。

    2.1.2 複合インデックス作成時のポイント

    インデックス定義はより絞り込める条件のカラムから順番に記述する、ただし例外あり

    2.1.3 SQL文記述時におけるインデックスの有効な利用方法

    SQLのOR条件式を工夫することで、インデックスの絞り込みを有効にする

    まず、上記のカラムdate、timeのインデックスを利用して検索しようとすると、プランナーは date > '2019/4/1' の条件で検索し、その後、date = '2019/4/1' AND time >= '12:00:00' の条件でも検索します。次にこれらの結果をマージするよう実行計画を立てます。この処理はコストが高いため、パフォーマンスが出ないことが考えられます。

    SQLにOR条件がある場合の処理の流れ

    そこで、ORの両辺にあるdateの条件が両方とも date >= ‘2019/4/1’ を満たすので、この条件をANDで追加します。

    追加するAND条件

    関数や演算を利用した条件なら「式インデックス」を利用する

    WHERE句の条件文で異なるデータ型による比較を行った場合の影響について

    2.2 実行計画を評価し制御する

    実行計画から時間を費やしている箇所を特定する

    各処理に費やした時間については、以下の結果になります。
    【上位ノード】131.686 - Seq Scanの時間(131.519) - Index Scanの時間(0.132) = 0.035 ms
    【下位ノード1】131.519 × 実行回数1回 = 131.519 ms
    【下位ノード2】0.012 × 実行回数11回 = 0.132 ms

    これらの情報を基に、実行計画の妥当性を確認します。例えば、Seq Scanで時間を費やしている場合はインデックスを追加することを検討します。しかし、loopsの回数が多く時間を費やしている場合は、結合方法を変更するなど、ノードの要素を強制的に変更することも検討してください。結合方法の変更については次の項目で説明しますが、コマンド「SET enable_nestloop = off」により一時的にNested Loopを抑止することで行うことも可能です。
    なお、【上位ノード】と【下位ノード1】において、推定時の行数(rows)が1であるのに対し、実行時の行数(rows)は11になっています。これは、統計情報が最新化されていない可能性が考えられます。この場合は、autovacuumの実行頻度の設定を見直すか、あるいは、手動でANALYZEコマンドを実行することで解決できます。

    カーソル利用時の実行計画について

    pg_hint_planを用いて、実行計画を制御する

    pg_dbms_statsを用いて、統計情報を固定化する

    2.3 クライアント側で無駄を削減する

    何度も実行するSQLは、プリペアド文を定義し再利用する

    • 1)プリペアド文で準備したSQLを繰り返し実行する時に、最初の5回目までは、毎回、パラメーターに合わせた実行計画(実行計画A1からA5とします)を作成します。
    • 2)6回目以降に実行する時は、パラメーターの値が未設定である汎用的な実行計画(実行計画Bとします)を作成し、今まで作成した実行計画A1からA5までの平均コストと、実行計画Bのコストを比較して、今後、汎用的な実行計画を利用するか否かを判定します。
    • 3)実行計画Bのコストが実行計画Aの平均コストよりもそれほど大きくない場合、それ以降のSQL実行で実行計画を毎回作成せず、汎用的な実行計画(実行計画B)を利用します。
      あるいは、実行計画Bのコストが実行計画A1からA5までの平均コストよりもかなり大きい場合は、パラメーターに合わせた実行計画を毎回作成して利用します。
    • 自動判定(上記の方法、デフォルト値)
    • 必ず汎用的な実行計画を利用する(理想的なプランについて、パラメーター値への依存度が低い場合に有効)
    • 必ずその都度実行計画を作成する(理想的なプランについて、パラメーター値への依存度が高い場合に有効)

    コネクションプーリングを使い、接続処理を省略する

    頻繁にPostgreSQLへの接続と切断を繰返すシステムのような場合、このコネクション処理がオーバーヘッドになります。その場合は、コネクションプーリングを用いることで、すでに接続されているコネクションを再利用でき、パフォーマンス改善につなげることができます。コネクションプーリングは、Pgpool-IIを利用したり、JDBCやNpgsql(.NET Data Provider)などのインターフェイスに組み込まれているものを利用したり、クライアント側でコネクションプーリング機能を作り込んだりすることで実現できます。

    ユーザー定義関数を用いて処理を関数化し、ネットワーク通信を省略する

    フェッチサイズを調整する

    • JDBCの接続文字列に設定できるdefaultRowfetchSizeパラメーターにより変更
    • ODBCのCache Sizeオプションにより変更

    こちらもおすすめ

    PostgreSQLについてより深く知る

    「FUJITSU Software DevTech Days 2021」の講演を配信

    大好評のうちに閉幕しましたオンラインイベント「FUJITSU ファンクションインデックス Software DevTech Days 2021」での各講演を配信しています。PostgreSQL 15に向けた展望や、Kubernetesなどのコンテナ技術を活用したデータベースの効率的な運用方法など見所満載です。ぜひご視聴ください!

    tシャツ Tシャツ ポンチ ラウンドヘムプルオーバー【マルチファンクション】

    『タイムセール実施中』
    ZOZO問い合わせ番号:55848319
    ショップ:index,インデックス
    ブランド:index,インデックス
    商品名:ポンチ ラウンドヘムプルオーバー【マルチファンクション】
    カテゴリ:トップス>Tシャツ/カットソー
    ブランド品番:C58-12203-2021-01
    素材:本体: コットン65 ファンクションインデックス ファンクションインデックス ファンクションインデックス ポリエステル33 ポリウレタン2% 別布部分: ポリエステル80 コットン20%
    原産国:中国製
    カラー:オフホワイト,ベージュ,パープル,グリーン系
    サイズ:36,38,40,42
    企画ID:1390974,1368602,1366806,1325665,1325661,1325659,1310675,1310674,1310673,1310103

    『タイムセール実施中』
    ZOZO問い合わせ番号:55848319
    ショップ:index,インデックス
    ブランド:index,インデックス
    商品名:ポンチ ラウンドヘムプルオーバー【マルチファンクション】
    カテゴリ:トップス>Tシャツ/カットソー
    ブランド品番:C58-12203-2021-01
    素材:本体: コットン65 ポリエステル33 ポリウレタン2% 別布部分: ポリエステル80 コットン20%
    原産国:中国製
    カラー:オフホワイト,ベージュ,パープル,グリーン系
    サイズ:36,38,40,42
    企画ID:1390974,1368602,1366806,1325665,1325661,1325659,1310675,1310674,1310673,1310103

    • 販売期間:2022年6月2日 11:00 ~ 2022年6月6日 2:00
    • 商品について詳しく知りたい
    • お届け日、発送日、送料が知りたい
    • 在庫状況、再入荷状況が知りたい 等

    レビューコメント

    • サイズ/ ちょうどよい
    • 生地/ 少し厚め
    • 伸縮性/ 普通
    • グリーン系
    • 38(レディース:Mサイズ相当)
    • サイズ/ 少し大きめ
    • 生地/ 少し厚め
    • 伸縮性/ 普通
    • 女性
    • 20代
    • 156cm~160cm
    • ベージュ
    • 38(レディース:Mサイズ相当)
    • オフホワイト
    • 40(L)
    • パープル
    • 38(M)

    販売ストア

    ZOZOTOWN PayPayモール店

    関連のおすすめブランド

    • 25円相当 (1%)

    ヤフー株式会社またはPayPay株式会社が、不正行為のおそれがあると判断した場合(複数のYahoo! JAPAN IDによるお一人様によるご注文と判断した場合を含みますがこれに限られません)には、表示された付与数では付与されない場合があります。

    【完全マスター】!Pythonのindexの使い方を徹底解説!

    【初心者向け】Pythonのリストを解説!データの追加方法や並び替え方がわかる! ファンクションインデックス 「Pythonのリストの使い方がわからない。誰か詳しく使い方を教えてほしい」 本記事ではこのような悩みを解決します。 .

    indexメソッドの使い方

    1. シーケンス . index ( ‘value’ )

    リストの要素が重複していない場合の使い方

    1. mylist = [ ‘aaa’ , ‘bbb’ , ‘ccc’ , ‘ddd’ , ‘eee’ ]
    2. print( mylist . index ( ‘bbb’ ) )
    3. # 実行結果
    4. 1
    5.
    6. print( mylist . index ( ‘eee’ ) )
    7. # 実行結果
    8. 4

    指定した要素が存在しない場合、ValueErrorが発生 するので注意してください。

    1. print( mylist . index ( ‘fff’ ) )
    2. ValueError : ‘fff’ is not in list

    リストの要素が重複している場合の使い方

    リストの要素が重複している場合の「index( )メソッド」は 最初に見つかった要素に対応するインデックスだけを返す ので注意してください。

    1. mylist = [ ‘aaa’ , ‘bbb’ , ‘ccc’ , ‘ccc’ , ‘aaa’ ]
    2. print ( mylist )
    3. # 実行結果
    4. [ ‘aaa’ , ‘bbb’ , ‘ccc’ , ‘ccc’ , ‘aaa’ ]
    5.
    6. print ( mylist . index ( ‘aaa’ ) )
    7. # 実行結果
    8. 0
    9.
    10. print ( mylist . index ( ‘ccc’ ) )
    11. # 実行結果
    12. 2

    1. [ i for i , x in enumerate ( list型変数 ) if x == value ]

    1. mylist = [ ‘aaa’ , ‘bbb’ , ‘ccc’ , ‘ccc’ , ‘aaa’ ]
    2.
    3. for idx , val in enumerate ( mylist ) :
    4. print ( idx , val )
    5.
    6. # 実行結果
    7. 0 aaa
    8. 1 bbb
    9. 2 ccc
    10. 3 ccc
    11. 4 aaa

    1. mylist = [‘aaa’, ‘bbb’, ‘ccc’, ‘ccc’, ‘aaa’]
    2. idxlist = [ ]
    3. for idx , val in enumerate ( mylist ) :
    4. if val == ‘ccc’ : ファンクションインデックス
    5. idxlist . append ( idx )
    6.
    7. print ( idxlist )
    8.
    9. # 実行結果
    10. [ 2 , 3 ]

    1. # 要素が1つだけ含まれている
    2. print ( [ i for i , x in enumerate ( mylist ) if x == ‘’bbb’ ] )
    3. # 実行結果
    4. [ 1 ]
    5.
    6. # リストに含まれていない値
    7. print ( [ i for i , x in enumerate ( mylist ) if x ファンクションインデックス == ‘fff’ ] )
    8. # 実行結果
    9. [ ]
    10.
    11. # 繰り返し使用する場合
    12. def my _ ファンクションインデックス index _ multi ( list1 , x ) :
    13. return [ i for i , _x in enumerate ( mylist ) if _x == x )
    14.
    15. print ( my _ index _ multi ( mylist , ‘aaa’ ) )
    16. # 実行結果
    17. [ 0 , 4 ]
    18.
    19. print ( my _ index _ multi ( mylist , ‘bbb’ ) )
    20. # 実行結果
    21. [ 1 ]
    22.
    23. print ( my _ index _ multi ( mylist , ‘fff’ ) )
    24. # 実行結果
    25. [ ]

    リストのリスト

    1. list1 = [ [ 111 , 222 , 333 ] , [ ‘red‘ , ‘blue’ , ‘green’ ] ]
    2. list2 = 222
    3. list3 = [ ‘red’ , ‘blue’ , ‘green’ ]
    4.
    5. x = list1 . index ( list2 )
    6. z = list1 . index ( list3 )
    7.
    8. print ( x )
    9. print ( z )
    10.
    11. # 実行結果
    12. ValueError : 222 is not in list

    最大値のインデックスを取得

    1. list = [ 111 , ファンクションインデックス 555 , 777 , 333, 777 ]
    2.
    3. print( list. index ( max ( list ) ) )
    4. #実行結果
    5. 2

    1. list = [ 111 , 555 , 777 , 333 , 777 ]
    2.
    3. print( [ i for i , v in enumerate ( list ) if v == max ( list ) ] )
    4. # 実行結果
    5. [ 2 , 4 ]

    リスト以外でindexメソッドを使う方法

    ファンクションインデックス
    1. tuple = ( ‘aaa’ , ‘bbb’ , ‘ccc’ )
    2. print ( tuple . index ( ‘bbb’ ))
    3. # 実行結果
    4. 1

    1. str = ‘HelloWorld’
    2. print ( str . index ( ‘l’ ) )
    3. # 実行結果
    4. 2

    また、 文字数を指定して抽出することもできます。

    1. str = ‘python’
    2.
    3. print ( str [ 0 ] )
    4. # 実行結果
    5. p
    6.
    7. print ( ファンクションインデックス str [ 5 ] )
    8. # 実行結果
    9. n
    10.
    11. #負の値を使用すると文字列の後ろから指定可能
    12. print ( str [ -1 ] )
    13. # 実行結果
    14. n
    15.
    16. print ( str [ -6 ] )
    17. # 実行結果
    18. p

    まとめ

    • indexとはシーケンスのある要素が何番目かということを表すもの
    • indexは0から始まり、負のインデックスは1番右側が-1となる
    • リストに含まれていない値を指定するとValueErrorが発生する
    • リストの要素が重複している場合は最初のインデックスだけを返す
    • indexメソッドはリスト以外にもタプルや文字列にも使用できる

    Pythonの個別指導なら『Tech Teacher』

    このBlogを運営する Tech Teacherは、Pythonを学習する社会人を対象に 、初心者から挫折した人まで、一人ひとりの目的や学習状況にあわせた個別指導を行っています。 ファンクションインデックス

    また、 オンライン指導 も選べるので、 自宅でも対面でも 受講できます。

    一人ひとりに最適化された完全マンツーマン指導を提供

    完全マンツーマン指導で着実に身につく!

    Tech Teacherでは 専任の教師が完全マンツーマン指導 を行います。
    学習状況や目標をしっかり把握した教師が、生徒様のご要望もふまえながら最適なオーダーメイドの指導をご提供します。

    お仕事と両立しながら続けられる!

    Tech Teacherなら、 受講日時や回数を生徒様のご都合に合わせて柔軟に調整 することができます。
    そのため、お仕事との両立がしやすく、プログラミング学習を継続的に学習することができます。忙しい合間にプログラミングを学びたいという方におすすめです。

    授業料は受けた分だけ!

    Tech Teacherでは、生徒様が 受けた授業の時間分だけ後払い で請求させていただきます。そのため、気軽にプログラミングの学習を始めることができます

    関連記事

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次
閉じる