如何解决搜索数据库表以确定列表中看不到的文件名
我正在处理磁盘上的平面文件,并且需要确保我从未两次处理同一文件。每个处理文件的文件名都存储在postgresql DB中,在下一次迭代中,我需要确定磁盘上看不见的文件并进行处理,即。我需要确定磁盘上文件名和数据库中文件名的设置差异。
当前,我的方法是从磁盘上的文件名创建CTE,并将其加入可见文件名表。磁盘上的文件列表很大并且不断变化,并且处理速度也在变慢。
这是当前查询:
WITH input(filename) AS (VALUES ${filenames.joinToString { "(?)" }})
SELECT input.filename FROM input
LEFT JOIN my_table pm ON input.filename ILIKE pm.filename
WHERE pm.filename IS NULL
${filenames.joinToString { "(?)" }}
扩展为(?),(?),(?)
之类的东西,具体取决于文件名参数的数量。
我该如何加快此过程?
我要做的一件事是在文件名列上添加一个索引。正确的选择是哪种索引?
解决方法
由于您使用的是ILIKE
,因此我不会在pm.filename
上放置索引,而是在LOWER(pm.filename)
上放置索引。这应该允许您删除ILIKE
,而选择性能更高的LIKE
。这也意味着您只能使用简单的B-tree
index,因为它可以与LIKE
一起正常工作。如果您使用通配符,LIKE
很有用,但如果不使用通配符,请使用常规的=
-等于。
最后,查询优化器很有可能已经对该查询做了很多工作,但是我建议您查看此查询的EXPLAIN (ANALYSE)
输出。我有一些改进的建议,但是对于它们是否会有所帮助或都将归结为相同的查询计划一无所知。这完全取决于您!
这将第一个查询的结果放在第一个列表中,并从第二个查询的结果中删除所有匹配项。缺点是返回的文件名是小写的。
SELECT LOWER(filename)
FROM (VALUES ${filenames.joinToString { "(?)" }}) AS input(filename)
EXCEPT ALL (SELECT LOWER(filename) FROM my_table pm)
此查询没有此缺点,它只返回my_table
中不匹配的所有文件名。
SELECT filename
FROM (VALUES ${filenames.joinToString { "(?)" }}) AS input(filename)
WHERE NOT EXISTS (
SELECT
FROM my_table pm
WHERE LOWER(pm.filename) = LOWER(input.filename)
)
最后一个查询可能与此等效,但是为了完整起见,我将其添加。
SELECT filename
FROM (VALUES ${filenames.joinToString { "(?)" }}) AS input(filename)
WHERE LOWER(filename) NOT IN (
SELECT LOWER(pm.filename)
FROM my_table pm
)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。