3

データベースにツリーを表すテーブルがあります。データはネストされたセットを使用して保存されます。ツリーを検索し、パターンに一致するノードとその祖先および子孫のみを返すクエリを作成したいと思います。これは私がこれまでに思いついたものです。

SELECT DISTINCT Node, Parent, Description
FROM Hierarchy 
INNER JOIN 
    (SELECT Lft, Rgt 
    FROM Hierarchy 
    WHERE Description LIKE '%SEARCHQUERY%') AS Matches 
ON (Hierarchy.Lft <= Matches.Lft AND 
    Hierarchy.Rgt >= Matches.Rgt) OR 
    (Hierarchy.Lft >= Matches.Lft AND 
    Hierarchy.Rgt <= Matches.Rgt) 
ORDER BY Description

このクエリは機能しますが、サブクエリが多くの説明に一致する場合は少し遅くなります。このクエリのパフォーマンスを向上させる方法についてのアイデアを探しています。

関連する場合は、Accessを使用しています。

私は自由で、このクエリを改善するためにテーブルの構造を変更する用意があります。テーブルには約8000ノードがあります。レコードの数は、アプリケーションの存続期間を通じてあまり変化しません。最大深度は5です。

パフォーマンスは通常の検索(最大200ノードを返す検索の場合は数秒)では許容できますが、病理学的な場合には数分かかります(たとえば、単一の母音を検索する場合。ただし、これらの場合でも、サブクエリの所要時間は短くなります。実行するのに1秒以上)。

4

3 に答える 3

1

私はおそらく元の質問から少し外れていますが、ここに行きます:

コメントで示唆されているように、書き直しの余裕があることを考えると、ツリー構造をモデル化する別の方法を調査する必要があります。特に、別のアプローチでかなり管理しやすい「固定深度」があることを考慮してください。

彼の「TheArtofSQL」のFaroultは、ノードが存在する「ブランチ」をエンコードする文字列フィールドでノードの位置を表すことに基づくアプローチを支持しています。(本のレビューと少しの議論については、このスラッシュドットスレッドを参照してください)。

これが私の意味のオンライン例です-ArtofSQLには、3つの異なるアプローチ(入れ子集合、親子関係テーブル、エンコードされたパスフィールド)を比較し、の戦闘順序を使用して、これに特化した本のセクション全体があります例としてウォータールーの軍隊(「X将軍の下にあるすべての大隊を一覧表示する」や「砲兵グループYの指揮官を見つける」などのクエリがたくさんあります)。

Faroultはパフォーマンスについてかなり熱狂的であり、本全体は、効率的なクエリを(再)作成する方法に関する非常に健全で実用的なアドバイスの非ベンダー固有のコレクションです。

于 2010-02-10T08:52:46.020 に答える
0

クエリが遅い理由はそのLIKE('%blah%')一部です。あなたが落とすことができれば、最初の%ものはかなりスピードアップします。または、 AccessがFULLTEXTインデックスをサポートしている場合は、[説明]フィールドに1つ入力して実行します。MATCH(Description) AGAINST ('blah')

于 2010-02-09T15:52:13.507 に答える
0

私はおそらくparent_idテーブルのフィールドだけを使用し、3方向の外部自己結合を使用して、ターゲットhierarchyレコード(適切にフィルタリングされたもの)とその親(存在する場合)および子(存在する場合)のレコードを取得します。

于 2010-02-09T05:28:10.853 に答える