db_select()で独自のクエリを作成するのではなく、node_load()を使用する必要がありますか?


6

私はのようなDrupal 7関数を使用することにかなり慣れていdb_select()ます。一方でnode_load()、非常に使いやすい、明らかですが、私は多くの場合、それは私が必要としないフィールドを返し、私は(いくつか必要になるフィールドが必要行うというフィールドを提供していないことが判明join得るために、複数可)。

したがって、独自のクエリを作成するnode_load()と、他のクエリと組み合わせて使用するよりもパフォーマンスが向上しますか?それともnode_load()、おそらくキャッシュなどから、何らかのパフォーマンスの向上が見られますか?

私はMySQLのパフォーマンス問題の専門家とはほど遠いですが、最終的に必要なものの一部のみを個別に取得する複数のクエリを使用するよりも、特定の単一のクエリを構築する方が良いようです(そして私が必要としないものの多く) )。

回答:


13

技術的には、はい、独自のdb_query()ステートメントを作成すると、データがより速く、オーバーヘッドが少なくなります。しかし、それは実際に物事を行うための「Drupalな方法」ではありません。

node_load()「静的」キャッシュを提供します。つまり、1つのページ要求で同じノードを2回ロードすると、DBに1回しかヒットしません。

使用しないことで実際に見逃しているのnode_load()は、すべてのAPIフックとサードパーティモジュールの統合です。CCKフィールドが必要な場合node_load()は、そのすべてのデータを取得します。手動のクエリでは、多くの結合が必要になります。

お気づきのように、現時点では必要のない追加の処理/ロードが数多く行われています。データが必要ない場合でも、技術的にデータを持たなくても害はありません。このルートに行きたいかどうかはあなた次第です。

IMOを使用する最大の理由node_load()は、追加のデータが不要な場合でも、標準化のためだけです。ある時点でどのようなデータがあるかを気にする必要はありません。完全に読み込まれたノードがあり、必要に応じてを使用してデータを調整するためのオプションが増えますhook_nodeapi()。あなたのコードを見る他の開発者は、彼らが何を使っているのかを理解するのにより簡単な時間を費やすでしょう。また、6か月後に新しい機能/表示フィールドを追加すると、クエリを調整する必要がなくなります。

node_loadは間違いなくリソースの独占ですが、私の経験ではそれを使用する方が良いことがわかりました。Drupal 7はnode_load_multiple()を提供することで状況を大幅に改善します。これは、その名前が示すように、複数のノードをロードするときのクエリの数を減らします。


使用する主な理由はnode_load()、Drupalの将来のバージョンとの互換性、および関数から返される結果を変更する可能性がある他のモジュールとの統合です。最初の点については、Drupal 7でそれが明らかです。完全なノードオブジェクトを取得するクエリは、Drupal 6で使用されるクエリとはかなり異なります。また、クエリに関連するデータベーステーブルも変更します。
kiamlaluno

また、ノードオブジェクトを作成するのに他のモジュールのフックが必要ない場合は、1つの巨大なSQLステートメントの方がはるかに高速です。高速結合、高速クエリDBへの1回のトリップは高速で、ノードを繰り返してノードに繰り返しロードするphpとは異なり、phpは他のモジュールにフックを要求します。各nidは、dbへの組み込みのトリップ(キャッシュまたはビルド)、およびphpでそれぞれを処理します。Youch。
texas-bronius 14年

5

jakarskaの回答で説明されているように、DBクエリだけnode_load()node_load_mutliple()はありません。彼らはあなたのサイトの有効化されたモジュールによって実装されたすべてのノード構築フックの呼び出しを処理します。

さらに、Drupal 7では、プラグ可能なフィールドストレージの導入により、再利用可能なコードで作業しているときに、フィールドデータが(メイン)データベースで使用できるかどうかがわかりません。原則としてnode_load()node_load_mutliple()EntityFieldQueryを使用してノードを照会します。あなたが唯一の複数のノードのための特定のフィールドが必要な場合にも使用することができるfield_attach_load()$options['field_id']の結果にEntityFieldQuery

だから、私がカスタムSQLクエリを実行するのはnode_load()node_load_mutliple()とがEntityFieldQuery提供するすべてのものが必要でなく、必要とされず、常に、そして常に格納されるデータに使用される場合を除いて、カスタムSQLクエリを使用しないでください。 SQLデータベース。


1

node_load()「Drupal way」です。つまり、この関数を呼び出すことにより、ノードの読み込みが開始されたときにAPIがモジュールにメッセージを送信するため、これらのモジュールは独自の情報を追加、変更、削除できます。はい、node_load()多くのクエリを使用するため、キャッシュを使用します。具体的なデータの選択に
使用できますdb_select()が、必ず正しいデータを収集・変更・削除してください。


0

ビューを注意深く作成して、必要なものをフィルタリングして関連付け、views_get_view_result()関数を使用して結果を取得できます。

そして注意深く言うと、必要なフィールドだけを使用するということです。たとえば、そのノードへのリンクを含むノードタイトルのフィールドを含めると、リンクなしでノードIDのみを使用するのではなく、ビューでのクエリがかなり長くなります。

Viewsは強力なクエリビルダーであり、プログラムで使用すると問題を解決するのに役立ちます。Drupalにやさしい簡単なクエリと、特定のエンティティからすべてのデータをロードするよりも速い結果を得ることができます。

作成時に生成されたクエリを表示するには、ビューモジュールを構成する必要があります。また、望ましくないオーバーライドを回避するために、ビューに「システム」などの名前を付けたりタグを付けたりすると便利です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.