min*_*.dk 8 postgresql tsvector
tsvector在列中存储值时,对于没有搜索项的记录,我应该存储空值tsvector还是NULL值?
有关系吗?
存储空载体的性能或存储开销是否有任何差异?
换句话说,当基于例如可空title列的值更新向量时,我是否需要始终将其计算为to_tsvector(coalesce(title,''))(因为在给定参数时to_tsvector返回)或者它是否足够?NULLNULLto_tsvector(title)
首先,SQL 的语义NULL是 的语义UNKNOWN,而某些数据类型也有“空”值。这些数据类型包括:
TEXT(''与 不一样NULL::TEXT)JSONand JSONB([]or 与or{}不同)NULL::JSONNULL:JSONBX[](ARRAY[]::X[]与 不一样NULL::X[])还有更多,包括TSVECTOR. 某些东西的空集合的语义总是与NULL值的语义略有不同,值是一个UNKNOWN集合(尽管通常只是用作不存在的集合)。当涉及到使用运算符时,这种区别特别明显,例如
'' || 'abc' = 'abc'但NULL || 'abc' IS NULLto_tsvector('cats ate rats') @@ to_tsquery('cat & rat') = true但NULL @@ to_tsquery('cat & rat') IS NULLTSVECTOR从这个意义上说,该决定首先应该是逻辑决定,而不是存储决定,基于以下问题:即使记录没有任何搜索词(proempty TSVECTOR) ,您是否仍然会使用记录的值?或者该功能根本不适用于该特定记录(专业NULL价值)?对于@@操作员来说,它可能不是那么相关,但对于||操作员和其他人来说绝对是这样。
答案并不明显,一般来说也没有明确的正确/错误方法。
如果这是您的应用程序中对性能高度敏感的情况(例如您有很多空TSVECTOR值),那么也许这个基准可以帮助您做出决定?
我在 Docker 中的 PostgreSQL 14.1 上运行了以下基准测试以获得此结果:
RUN 1, Statement 1: 2.91145
RUN 1, Statement 2: 1.00000 -- The fastest run is 1. The others are multiples of 1
RUN 2, Statement 1: 2.80509
RUN 2, Statement 2: 1.05232
RUN 3, Statement 1: 2.78001
RUN 3, Statement 2: 1.00202
RUN 4, Statement 1: 2.74319
RUN 4, Statement 2: 1.00524
RUN 5, Statement 1: 2.75808
RUN 5, Statement 2: 1.00045
Run Code Online (Sandbox Code Playgroud)
SELECT v @@ to_tsquery('cat & rat')是v tsvector = to_tsvector('');SELECT NULL @@ to_tsquery('cat & rat')所涉及的事实NULL可能会导致运算符算法中的捷径,与在基准测试中@@查询空值相比,它的性能提高了 2.7 倍。因此,在性能方面TSVECTOR使用似乎确实有好处。NULL
显然,这只是一个基准,不一定反映现实世界的用例,但它应该给您一些潜在差异的提示。
基准代码
对于复制或改编,这里有一个基于此技术的基准。
RUN 1, Statement 1: 2.91145
RUN 1, Statement 2: 1.00000 -- The fastest run is 1. The others are multiples of 1
RUN 2, Statement 1: 2.80509
RUN 2, Statement 2: 1.05232
RUN 3, Statement 1: 2.78001
RUN 3, Statement 2: 1.00202
RUN 4, Statement 1: 2.74319
RUN 4, Statement 2: 1.00524
RUN 5, Statement 1: 2.75808
RUN 5, Statement 2: 1.00045
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
588 次 |
| 最近记录: |