我character varying在 postgres 中有一个字段,其中包含一组以 1 个空格分隔的字符串。例如:
--> one two three <----> apples bananas pears <--我放置-->并<--显示字符串开始和结束的位置(它们不是存储字符串本身的一部分)
我需要查询此字段以查明整个字符串是否包含某个单词(例如 apple)。一个可能的查询是
SELECT * FROM table WHERE thefield LIKE '%apple%'
Run Code Online (Sandbox Code Playgroud)
但它很糟糕并且不会扩展,因为 b-tree 索引仅在模式附加到字符串的开头时才扩展,而在我的情况下,搜索的字符串可以定位在字段中的任何位置。
你建议如何解决这个问题?
postgresql indexing database-design pattern-matching postgresql-performance
我想从导入PostgreSQL 9.3.5的OpenStreetMap数据库中检索具有给定名称的方法,操作系统是Win7 64位.为了有点容错,我使用了Postgres的unaccent扩展.
我的查询如下:
SELECT * FROM germany.ways
WHERE lower(tags->'name') like lower(unaccent('unaccent','Weststrasse'))
Run Code Online (Sandbox Code Playgroud)
查询计划:
Seq Scan on ways (cost=0.00..2958579.31 rows=122 width=465)
Filter: (lower((tags -> 'name'::text)) ~~ lower(unaccent('unaccent'::regdictionary, 'Weststrasse'::text)))
Run Code Online (Sandbox Code Playgroud)
奇怪的是,此查询使用顺序扫描方式,尽管索引存在于lower(tags->'name'):
CREATE INDEX ways_tags_name ON germany.ways (lower(tags -> 'name'));
Run Code Online (Sandbox Code Playgroud)
一旦我从查询中删除unaccent,Postgres就会使用索引:
SELECT * FROM germany.ways
WHERE lower(tags->'name') like lower('Weststrasse')
Run Code Online (Sandbox Code Playgroud)
查询计划:
Index Scan using ways_tags_name on ways (cost=0.57..495.43 rows=122 width=465)
Index Cond: (lower((tags -> 'name'::text)) = 'weststrasse'::text)
Filter: (lower((tags -> 'name'::text)) ~~ 'weststrasse'::text)
Run Code Online (Sandbox Code Playgroud)
为什么无法防止Postgres使用索引?在我看来,这没有意义,因为在执行实际查询之前,应该已经完全知道unaccent(变音符号删除等)的结果.所以Postgres应该能够使用索引.使用unaccent时如何避免seq扫描?
有人可以解释这三个查询之间的性能差异吗?
concat() 功能:
explain analyze
select * from person
where (concat(last_name, ' ', first_name, ' ', middle_name) like '%???%');
Seq Scan on person (cost=0.00..4.86 rows=1 width=15293) (actual time=0.032..0.140 rows=6 loops=1)
Filter: (pg_catalog.concat(last_name, ' ', first_name, ' ', middle_name) ~~ '%???%'::text)
Total runtime: 0.178 ms
Run Code Online (Sandbox Code Playgroud)
SQL标准串联||:
explain analyze
select * from person
where ((last_name || ' ' || first_name || ' ' || middle_name) like '%???%');
Seq Scan on person (cost=0.00..5.28 rows=1 width=15293) (actual time=0.023..0.080 rows=6 loops=1)
Filter: ((((((last_name)::text …Run Code Online (Sandbox Code Playgroud) sql postgresql concatenation pattern-matching postgresql-performance
在PostgreSQL中,我想根据某些条件选择一行,但如果没有符合条件的行,我想返回第一行.该表实际上包含一个序数列,因此任务应该更容易(第一行是序号为0的那一行).例如:
SELECT street, zip, city
FROM address
WHERE street LIKE 'Test%' OR ord = 0
LIMIT 1;
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,没有办法保证匹配的记录的顺序,我没有任何东西可以按顺序排序.使用单个SELECT语句执行此操作的方法是什么?
我有一个用户表,它包含位置列。我使用 varchar_pattern_ops 索引了位置列。但是当我运行查询规划器时,它告诉我它正在执行顺序扫描。
EXPLAIN ANALAYZE
SELECT * FROM USERS
WHERE lower(location) like '%nepa%'
ORDER BY location desc;
Run Code Online (Sandbox Code Playgroud)
它给出以下结果:
Sort (cost=12.41..12.42 rows=1 width=451) (actual time=0.084..0.087 rows=8 loops=1)
Sort Key: location
Sort Method: quicksort Memory: 27kB
-> Seq Scan on users (cost=0.00..12.40 rows=1 width=451) (actual time=0.029..0.051 rows=8 loops=1)
Filter: (lower((location)::text) ~~ '%nepa%'::text)
Planning time: 0.211 ms
Execution time: 0.147 ms
Run Code Online (Sandbox Code Playgroud)
我已经通过 stackoverflow 进行了搜索。发现大多数答案都类似于“postgres 在大表中执行顺序扫描,以防索引扫描速度变慢”。但我的桌子也不大。
我表中的索引users是:
"index_users_on_lower_location_varchar_pattern_ops" btree (lower(location::text) varchar_pattern_ops)
Run Code Online (Sandbox Code Playgroud)
到底是怎么回事?
我有一个包含 220 万行的表。
Table "public.index"
Column | Type | Modifiers
-----------+-----------------------------+-----------------------------------------------------
fid | integer | not null default nextval('index_fid_seq'::regclass)
location | character varying |
Indexes:
"index_pkey" PRIMARY KEY, btree (fid)
"location_index" btree (location text_pattern_ops)
Run Code Online (Sandbox Code Playgroud)
该位置是文件的完整路径,但我需要使用文件所在文件夹的名称进行查询。该文件夹名称在表中是唯一的。
为了避免%一开始,我搜索我知道的完整路径:
select fid from index where location like '/path/to/folder/%'
Run Code Online (Sandbox Code Playgroud)
解释分析:
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on index (cost=0.00..120223.34 rows=217 width=4) (actual time=1181.701..1181.701 rows=0 loops=1)
Filter: ((location)::text ~~ '/path/to/folder/%'::text)
Rows Removed by Filter: 2166034
Planning time: 0.954 ms
Execution time: 1181.748 ms
(5 rows) …Run Code Online (Sandbox Code Playgroud) 我有一个posts带有类型列的Postgres 表jsonb基本上是一个扁平的标签数组。
我需要做的是以某种方式运行一个 LIKE 查询 tags列元素以便我可以找到具有以部分字符串开头的标签的帖子。
这样的事情在 Postgres 中可能吗?我一直在寻找超级复杂的例子,但没有人描述过这种基本和简单的场景。
我当前的代码可以很好地检查是否有具有特定标签的帖子:
select * from posts where tags @> '"TAG"'
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种在以下方面运行某些东西的方法
select * from posts where tags @> '"%TAG%"'
Run Code Online (Sandbox Code Playgroud) 我有一个包含超过 30,000,000 个条目的数据库。当对字段执行查询(包括ORDER BY子句)时text,=运算符会产生相对较快的结果。然而我们注意到,当使用该LIKE运算符时,查询变得非常慢,需要几分钟才能完成。例如:
SELECT * FROM work_item_summary WHERE manager LIKE '%manager' ORDER BY created;
对正在搜索的关键字创建索引当然会大大加快查询速度。问题是我们必须支持对任意模式和任意列的查询,使得这个解决方案不可行。
我的问题是:
LIKE查询比查询慢得多=?我想检查另一列中是否包含列字符串。
表电子邮件列表:
complete_email
---------------------------------
zazumba@hotmail.com
jere@yahoo.com
maryhelp@aol.com
neil@cde.de
john_smith@zodll.ne
Run Code Online (Sandbox Code Playgroud)
表电子邮件部分:
username
--------------------
zazumba
maryhelp
neil
Run Code Online (Sandbox Code Playgroud)
我要执行的查询:
select e.complete_email
from emailslist e, emailpartial ep
where e.complete_email like '%ep.username%';
Run Code Online (Sandbox Code Playgroud)
我期望这样的结果:
complete_email
---------------------------
zazumba@hotmail.com
maryhelp@aol.com
neil@cde.de
Run Code Online (Sandbox Code Playgroud)
但是,这不是编写此 sql 查询的正确方法。有人可以澄清我该如何写吗?
谢谢,塞缪尔
我需要在PostgreSQL 8.4中实现一个正则表达式(据我所知)匹配.似乎正则表达式匹配仅在9.0+中可用.
我的需求是:
当我提供输入时,14.1我需要得到这些结果:
14.1.1
14.1.2
14.1.Z
...
Run Code Online (Sandbox Code Playgroud)
但排除:
14.1.1.1
14.1.1.K
14.1.Z.3.A
...
Run Code Online (Sandbox Code Playgroud)
该模式不限于单个字符.总有一种可能性,像这样的格局将呈现:14.1.1.2K,14.1.Z.13.A2等等,因为该模式提供给用户.应用程序无法控制模式(它不是版本号).
知道如何在Postgres 8.4中实现这一点吗?
再问一个问题我的问题解决了在存储过程中的Postgres 8.4中转义LIKE模式或regexp字符串
postgresql ×10
sql ×6
indexing ×5
arrays ×1
jsonb ×1
optimization ×1
regex ×1
sql-limit ×1
unaccent ×1