这个数据库模式和前缀查询有改进吗?

Is there an improvement to this DB schema and prefix like query?

我已经对这个 postgres 数据库模式和查询进行了一段时间的思考,我想我需要一双新的眼睛来理解 if/how 它可以改进。我的模式和查询相当简单,这就是为什么 600-700 毫秒的查询时间 感觉 是错误的,但也许这就是事实。

作为背景,我有一个 table IP,其中包含有关 IP 地址的基本信息,第二个 table 包含通过 has 映射回 IP table 的 DNS 名称许多外键。所讨论的数据的一个示例子集 运行 包含约 500 万个 IP 和约 3900 万个关联域。 table 架构如下所示:

这允许像这个问题有关的查询:

SELECT ips.id, domain, ip FROM "ips" JOIN domains d ON ips.id = d.ip_id WHERE d.domain like '%.ford.com' ORDER BY ips.id desc LIMIT 100

问的问题是“给我每个 DNS 名称以 ford.com 结尾的 IP”。 order by 和 limit 是为了启用此处描述的键集分页 keyset pagination

查询的示例分析如下。正如我在介绍中所解释的那样,它的平均值在 60​​0-700 毫秒范围内,其中大部分 (94%) 是域字段上 gin_trgrm_ops 索引的域模糊搜索。

查询分析

这是橡皮鸭调试的经典案例!在写这篇文章时,我有了一个深刻的见解,大大减少了查询时间!

后缀模糊搜索比前缀搜索快得多。 (foo% vs %bar) 所以我所做的是在数据库中的域字段上使用反向函数,结果是 (ford.com => moc.drof) 并切换查询使用后缀模糊搜索:

SELECT ips.id, domain, ip FROM "ips" JOIN domains d ON ips.id = d.ip_id WHERE reverse(d.domain) like 'moc.drof.%' ORDER BY ips.id desc LIMIT 100

这会产生低于 150 毫秒的查询!这里有一个很好的解释:https://www.alibabacloud.com/blog/postgresql-fuzzy-search-best-practices-single-word-double-word-and-multi-word-fuzzy-search-methods_595635

我仍然乐于接受有关如何改进它的建议,但我对此非常满意!