コードキッチンでは、通常、データベースの設定、特に互換性の設定に時間をかけます。アプリケーション開発者と議論していると、「あ、これ変えたことない」「影響がよくわからないから触らないほうがいい」と言われることがよくあります。
これらの設定は、アプリケーションのパフォーマンスや動作に劇的な影響を与える可能性があるため、これらの「秘密の」設定について説明するブログ記事のシリーズを開始しました。
互換性設定のパート1 – QUERY BY FORMULA
これらの設定は、4Dをバージョン2004のように強制的に動作させ、機能セットとパフォーマンスを低下させます。そして、とても簡単に変更できるのですが、顧客は未知の副作用を恐れているのです。
QUERY BY FORMULAは、v2004ではかなり遅く(すべてのレコードがクライアントに転送されるため)、多くの付加価値がなかった。そのため、ほとんどの開発者はこれを無視していた。このルールはv11で変更された。
QBFコマンド(このブログ記事では短くまとめています)は、画像のサイズやテキストの長さを検索するような計算を使用することができます。この機能の利点はかなり明白です。しかし、このような計算はインデックスを使うことができないので、インデックス付きのクエリよりも遅いのです。
しかし、QBFコマンドはもっと多くのことができるのです。括弧で囲んだクエリグループを結合することができます。OR ((field1=50) and (field2=”B”)).
QBFコマンドを使用しない場合、2つのクエリを実行し、セットを使用することになり、ネットワークトラフィックが大幅に増え、ネットワークのパフォーマンスに依存し、4D Serverへの負荷が大きくなります。4D Server のクエリオプティマイザは、同じテーブルのフィールド、あるいは関連するテーブルのフィールドに対して、このような条件を処理する最適な(最速の)方法を自動的に検出します。
そして何より、構造モードでリンクが描かれていない場合でも、独自にリレーションを構築することができます(別名、ジョイン)。QUERY BY FORMULA Uses SQL Joins” オプションを有効にすると、クエリを実行するために動的にリレーションを構築することができます。
QUERY BY FORMULA Uses SQL Joins」オプションはSQLとは全く関係ないので混乱するかもしれませんが、「QBFは動的なリレーションをサポートしている」と考えた方がよいでしょう。
簡単な構造を例にしてみましょう。
両方とも QUERYと QUERY BY FORMULAのようなリレーションを使った検索ができるようになった。
QUERY BY FORMULA([Table_2];[Table_1]Field_2="1")
しかし、QBFだけは、定義された関係がすでに存在することを要求するのではなく、関係を明示的に定義することができます(あらゆる可能な関係を使用することができます)。さて、この2つのテーブルの間に、4Dリレーションとしてまだ存在しない、2つ目の論理的な接続があると想像してみよう …フィールド3とフィールド2です。QBYでは、リレーションをその場で指定することができます。
QUERY BY FORMULA([Table_2]; ([Table_1]ID=$var)&\
([Table_1]Field_2=[Table_2]Field_3))
注意: 動的結合を使用する場合、異なるテーブルの 2 つのフィールドを比較する必要があります。クエリの一部であれば、これは自動的に結合として処理され、関係が定義されます。
別のテーブルの値を検索したい場合は、まずその値をローカル変数に代入しなければなりません。これは、定数として使用したいことを明確に定義するものです。
QUERY BY FORMULA Uses SQL Joins” オプションを有効にすることは、”新しい” クエリーエディター(つまり、v14で導入されたクエリーエディター)でリレーションを使用できるようにするために必須である。理由は簡単で、それは内部的に QUERY BY FORMULAコマンドを内部的に使用するからです。
まとめ
- QUERY BY FORMULAは、括弧を使って複雑な検索条件を表現することができます。 QUERYは、複数の OR 条件または複数の AND 条件のみを許可し、その両方を組み合わせることはできません。
- QUERY BY FORMULA結合と動的なクエリをサポートします。
- QUERY BY FORMULA画像サイズなどの数式を使用することができます。
- QUERY BY FORMULAはサーバ上で実行されるため (通常の QUERYの組み合わせと比較して、ネットワークトラフィックの発生が少ないため、同じかそれ以上の速度が得られます。 QUERYとセット操作の組み合わせに比べ、ネットワークトラフィックが少ないため、同じかそれ以上の速度が得られます。
注意:上記はすべて、古典的な4Dランゲージに対して言えることです。ORDAベースのコードは、常にサーバー上で実行されます。
互換性を有効にするために必要な移行作業
上記の設定は、4D v2004 またはそれ以前のバージョンで作成された構造体に対してのみ、互換性ダイアログで確認することができます。もし、これらの設定が表示されない場合は、あなたの構造体は新しく、常にv11モードで動作しているので、問題ないでしょう。
デザインモードでFindオプションを使用して、以下のものを検索します。 QUERY BY FORMULA.あなたの構造は「遅い」v2004モードなので、リストは短いはずです。各結果をダブルクリックして、コードを確認してください。
数式に定数が使われている限りは、次のようになります。
QUERY BY FORMULA([Table_2];[Table_1]Field_2="1")
または
QUERY BY FORMULA([Table_2];[Table_1]Field_2=$var)
// similar for var or <>var
すべて順調で、何もすることはありません。4D Remoteは、変数を解釈し、その内容をサーバーに送信します(定数と同様)。サーバーでクエリを実行しても、常にクライアントの値が使用されます。
式がメソッドである場合、例えば
QUERY BY FORMULA([Table_2];RunQuery)
メソッドを開いて、その内容を確認する必要があります。メソッドにパラメータが渡される場合、そのメソッドは汎用的である可能性が高いです(しかし、まだ確認する必要があります)。パラメータが渡されない場合は、失敗する可能性が高い。
RunQueryにパラメータが含まれているとします。
$0:= ([Table_2]=myvar)
myvar の内容は、4D Remote と 4D Server で異なるので、4D Server でこのメソッドを実行すると、失敗します。異なる結果を返します。
この問題を解決するには、2つの方法があります。上記のような単純なクエリの場合、単純にRunQuery(myvar) と書き換えて、メソッドの中で$1 を使用すれば問題は解決します。
しかし、本当に複雑なメソッドを見つけるかもしれません。何千行ものコード、ドキュメントなし、20年前に書かれたもの。20年前に書かれたもので、1年に1回しか使われない。これは、最小限の影響に対して、多くの作業とエラーのリスクを伴うものです。この問題を回避するには、このコードをv2004モードでのみ実行し、他はすべてモダンモードで実行するようにすればよいのです。
SET DATABASE PARAMETER(Query by formula on server;1)
QUERY BY FORMULA ([Table_2];RunQuery)
SET DATABASE PARAMETER (
Query by formula on server;0)
SET DATABASE PARAMETERは、その場でモードを変更することができるので、めったに使わないコードに何時間もかける必要がなくなります。
最後に、フィールドが結合機能を阻害するような使われ方をしていないかチェックする必要があります。v2004では、[Table_1]Field_2=[Table_2]Field_3 のような式は、Field_3の内容を使用して、静的/固定コンテンツを検索していると解釈されます。QUERY BY FORMULA Uses SQL Joins」オプションを有効にすると、これは結合として解釈されます。
したがって、すべてのQBFをチェックして、”=”演算子の右側でフィールド名を使用しているかどうかを確認する必要があります。もしそうなら、それをローカル変数に代入し、そのローカル変数をクエリで使用します。
の出現をすべて確認したら QUERY BY FORMULAをすべてチェックしたら、両方のオプションを有効にする準備ができています。
高速検索を楽しむ…