问题: 我想为我的用户提供类似 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/