如果我想在一个表中搜索一行,并且精度递减,例如:
SELECT * FROM image WHERE name LIKE 'text' AND group_id = 10 LIMIT 1
如果没有结果,请尝试以下方法:
SELECT * FROM image WHERE name LIKE 'text' LIMIT 1
如果没有结果,试试这个:
SELECT * FROM image WHERE group_id = 10 LIMIT 1
有没有可能只用一个表达式就能做到这一点?
当我有三个或更多的搜索参数而不是两个时,也会出现一个问题。有没有一个通用的解决方案?当然,当搜索结果按其相关性排序时,它会很方便。
4条答案
按热度按时间bprjcwpo1#
我不认为在找到所需结果之前分别运行这些查询有什么问题。虽然有一些方法可以将这些查询合并到一个查询中,但这些方法最终会变得更复杂、更慢,这不是您所希望的。
您应该考虑在一个事务处理中运行所有查询,最好是在可重复读取隔离级别中运行,这样可以获得一致的结果,同时避免设置重复事务处理的开销。此外,如果明智地使用预准备语句,则所产生的开销几乎与在一个组合语句中运行所有三个查询的开销相同。
k5hmc34c2#
这将是一种伪解决方案方法,但我不完全确定您的场景中的语法是否允许这样做
xqkwcwgp3#
测试设置
Indexes是性能的关键要素。理想情况下,除了主键之外,还创建以下两个:
第二个 * 可能 * 不需要,具体取决于数据分布和其他详细信息。请参阅:
查询
**更新:**在Postgres 11或更高版本中,当
Parallel Append
用于大集合时,这将变得不可靠!请考虑以下问题和答案(包括我的答案中的可靠替代方案):这应该是对您的案例而言最快的查询:
fiddle
古老的SQLFIDLE
不带通配符的
LIKE
等效于=
LIMIT
子句适用于整个查询。Postgres非常聪明,不会在找到足够的行来满足LIMIT
时立即执行UNION ALL
后面的分支。因此,对于查询的 * 第一个 *SELECT
中的匹配项,EXPLAIN ANALYZE
的输出如下所示(向右滚动!):大胆强调我的。
不要 * 添加外部
ORDER BY
子句,这将使效果无效。那么Postgres在返回顶部行之前必须考虑所有行。最后的问题
有没有一个通用的解决方案?
这是一般解决方案。根据需要添加任意多个
SELECT
语句。当然,当搜索结果按其相关性排序时,它会派上用场。
结果中只有一行具有
LIMIT 1
。这是一种空排序。qv7cva1a4#
现在已经很晚了,我不想写出一个完整的解决方案,但是如果我需要的话,我可能会创建一个客户function,它返回一个客户类型、记录或表(取决于您的需要)。
根据PostgreSQL的版本(以及可用的扩展),您可以传入hstore或json,然后dynamically来构建查询。
也许不是最好的答案,但它不仅仅是一个评论,希望一些思考的食物。