1

問題: Excel グリッドのようなクライアント側アプリケーションをユーザーに提供したいと考えています。そのクライアントは、ネットワーク接続を介して PostgreSQL サーバーにアクセスします。クライアントは「検索」機能を提供します。一致する結果のみをフィルタリングして表示する代わりに、「検索」機能は、グリッド内の最初の一致する行にジャンプするだけです。(Excel の「検索」機能のように)

帯域幅の使用量を減らし、不十分な LIMIT/OFFSET-Selects を防ぐために、サーバー側のカーソルで PostgreSQL を使用して、並べ替えられたテーブルをスクロールできるようにしています。

BEGIN WORK; 
DECLARE mCursor SCROLL CURSOR FOR 
    SELECT * 
    FROM table 
    ORDER BY xyz

結果データのスクロールと取得は、クライアントがグリッド内をスクロールするたびに Move/Fetch を呼び出すことによって処理されます。

MOVE FORWARD/BACKWARD <offset> IN mCursor; FETCH 40 FROM mCursor;

ここで、「検索」機能を追加したいと思います。魔女はインデックスを使用して、最初に一致する結果オフセットを見つけます。この機能を統合する唯一の方法は、新しい接続を開いて次のクエリを実行し、カーソルを返された行番号に移動することです。

SELECT t.rowNo 
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY ColumnName ASC) AS rowNo 
    FROM table
) t 
WHERE t.ColumnName LIKE 'xyz%' 
LIMIT 1

問題: インデックスを使用できないため、このクエリは非常に遅くなります (~300k 行で 2 ~ 3 秒)。

このタスクをより効率的に統合する他の方法はありますか?

おそらく、インデックスデータからオフセットを直接読み取ることによってですか?または、カーソル内でクエリを開始しますか? または、この機能を可能にするデータベースシステムはありますか?

4

1 に答える 1

1

パターンが。で始まっている場合にのみ、インデックスを使用することはできません%

問題は、インデックスを使用できないことではなく、すべてのテーブル行を列挙するためにインデックス全体をスキャンする必要があることだと思います。説明を表示します。

これにより、インデックススキャンが検索されたパターンまで制限されます

SELECT min(t.rowNo)
FROM (
    SELECT 
        ROW_NUMBER() OVER (ORDER BY ColumnName ASC) AS rowNo, 
        ColumnName 
    FROM table
    where ColumnName <= 'xyz' || repeat('z', 100) -- Get all possible like 'xyz%'
) t 
WHERE t.ColumnName LIKE 'xyz%' 
于 2012-12-21T12:53:44.000 に答える