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;

现在我想添加“查找”功能女巫使用索引来查找第一个匹配的结果偏移量。我知道集成此功能的唯一方法是打开一个新连接并运行以下查询,然后将光标移动到返回的 rowNo:

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 回答