performance - 使用 INDEX 将光标滚动到第一个搜索结果

标签 performance postgresql indexing cursor

问题: 我想为我的用户提供类似 Excel 网格的客户端应用程序。该客户端通过网络连接访问 PostgreSQL-Server。 客户端提供“查找”功能。 “查找”功能不是过滤并仅显示匹配结果,而是跳转到网格中的第一个匹配行。 (类似于 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 秒)。

是否有其他方法可以更有效地集成此任务?

也许直接从索引数据中读取偏移量?或者通过在 Cursor 中启动查询?或者是否有允许此功能的数据库系统?

最佳答案

仅当模式以 % 开头时才可能使用索引。

我想问题不在于它不能使用索引,而在于它必须扫描整个索引以枚举所有表行。显示说明。

这会将索引扫描限制为搜索到的模式

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%' 

关于performance - 使用 INDEX 将光标滚动到第一个搜索结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13973147/

相关文章:

sql - 如何过滤数据库中不存在的模型列的值?

c++ - 计算密集型C/C++程序的典型性能瓶颈是什么

postgresql - 如何在 where 子句中使用 sum 来计算平均值

json - 从 GROUP BY 语句在 Postgresql 中创建 JSON 值

arrays - 数组的 VBScript 索引位置

python - 将值捕捉到某些网格的高效 pythonic 方法

python - 将 Python 连接到 Heroku PostgreSQL 数据库?

node.js - 在一组点中查找比给定距离(接近度)更近的对

MySql 索引在范围扫描中的工作方式不同

c# - 没有目标的.net委托(delegate)比目标慢