- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在玩 pg_trgm
扩展,我有点困惑。这是 session :
postgres=# create table t(i int, x text);
CREATE TABLE
postgres=# insert into t select i, random()::text from generate_series(1,50000000) as i;
INSERT 0 50000000
postgres=# explain analyze select * from t where x ilike '%666666%';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Gather (cost=1000.00..531870.29 rows=12954 width=36) (actual time=131.436..11408.176 rows=432 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on t (cost=0.00..529574.89 rows=5398 width=36) (actual time=108.771..11304.946 rows=144 loops=3)
Filter: (x ~~* '%666666%'::text)
Rows Removed by Filter: 16666523
Planning Time: 0.121 ms
Execution Time: 11408.279 ms
(8 rows)
postgres=# explain analyze select * from t where x ilike '%666666%';
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Gather (cost=1000.00..580654.94 rows=5000 width=21) (actual time=124.986..11070.983 rows=432 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on t (cost=0.00..579154.94 rows=2083 width=21) (actual time=72.207..11010.876 rows=144 loops=3)
Filter: (x ~~* '%666666%'::text)
Rows Removed by Filter: 16666523
Planning Time: 0.283 ms
Execution Time: 11071.065 ms
(8 rows)
postgres=# create index i on t using gin (x gin_trgm_ops);
CREATE INDEX
postgres=# analyze t;
ANALYZE
postgres=# explain analyze select * from t where x ilike '%666666%';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on t (cost=54.75..18107.93 rows=5000 width=21) (actual time=116.114..26995.773 rows=432 loops=1)
Recheck Cond: (x ~~* '%666666%'::text)
Rows Removed by Index Recheck: 36257910
Heap Blocks: exact=39064 lossy=230594
-> Bitmap Index Scan on i (cost=0.00..53.50 rows=5000 width=0) (actual time=75.363..75.363 rows=592216 loops=1)
Index Cond: (x ~~* '%666666%'::text)
Planning Time: 0.389 ms
Execution Time: 26996.429 ms
(8 rows)
postgres=# explain analyze select * from t where x ilike '%666666%';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on t (cost=54.75..18107.93 rows=5000 width=21) (actual time=128.859..29231.765 rows=432 loops=1)
Recheck Cond: (x ~~* '%666666%'::text)
Rows Removed by Index Recheck: 36257910
Heap Blocks: exact=39064 lossy=230594
-> Bitmap Index Scan on i (cost=0.00..53.50 rows=5000 width=0) (actual time=79.147..79.147 rows=592216 loops=1)
Index Cond: (x ~~* '%666666%'::text)
Planning Time: 0.252 ms
Execution Time: 29231.945 ms
(8 rows)
如您所见,在没有索引的情况下,查询比使用索引快两倍。目前只有默认的 PostgreSQL 设置(共享缓冲区、工作内存等)
我错过了什么?
PS: PostgreSQL 11.5 (Ubuntu 11.5-1.pgdg18.04+1) on x86_64-pc-linux-gnu, gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0, 64-bit 编译
PPS:使用 gist
索引会更慢。
最佳答案
tldr:trigrams 可能不擅长搜索由重复 N 次的单个字符组成的模式(例如 666666
),因为只存在 1 个非终结符 trigram,可以 在搜索空间中出现率很高。
当使用 gin-index 时,行的位图太大而无法放入内存,因此它存储对页面的引用,数据库必须对这些页面执行进一步的重新检查扫描。如果重新检查的页面数量很少,索引的使用仍然是有益的,但是如果重新检查的页面数量很多,索引的性能就会很差。这在您的解释输出中由以下几行突出显示
Recheck Cond: (x ~~* '%666666%'::text)
Rows Removed by Index Recheck: 36257910
Heap Blocks: exact=39064 lossy=230594
关于测试数据,此问题特定于您的搜索字符串,即 666666
。
如果你运行 select pg_trgm('666666')
,你会发现:
show_trgm
-------------------------
{" 6"," 66","66 ",666}
(1 row)
甚至不会在相似的上下文中生成前 3 个三元组 (用户 jjanes 建议的更正)。搜索索引会得到所有包含 666
的页面。您可以通过使用 ... ilike '%666%'
运行 explain analyze 查询来验证这一点,并获得与上面相同的 Heap Blocks
输出。
如果您使用模式 123456
进行搜索,您会发现它的性能要好得多,因为它会生成更大的 trigram 集来进行搜索:
show_trgm
-------------------------------------
{" 1"," 12",123,234,345,456,"56 "}
(1 row)
在我的机器上,我得到以下信息:
|------------------------------------|
| pattern | pages rechecked |
| | exact | lossy | total |
|------------------------------------|
| 123456 | 600 | | 600 |
| 666666 | 39454 | 230592 | 270046* |
| 666 | 39454 | 230592 | 270046* |
|------------------------------------|
*this is rougly 85% of the total # of pages used for the table 't'
这是解释输出:
postgres=> explain analyze select * from t where x ~ '123456';
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on t (cost=90.75..18143.92 rows=5000 width=22) (actual time=110.962..113.509 rows=518 loops=1)
Recheck Cond: (x ~ '123456'::text)
Rows Removed by Index Recheck: 83
Heap Blocks: exact=600
-> Bitmap Index Scan on t_x_idx (cost=0.00..89.50 rows=5000 width=0) (actual time=110.868..110.868 rows=601 loops=1)
Index Cond: (x ~ '123456'::text)
Planning time: 0.703 ms
Execution time: 113.564 ms
(8 rows)
postgres=> explain analyze select * from t where x ~ '666666';
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on t (cost=54.75..18107.92 rows=5000 width=22) (actual time=137.143..18111.609 rows=462 loops=1)
Recheck Cond: (x ~ '666666'::text)
Rows Removed by Index Recheck: 36258389
Heap Blocks: exact=39454 lossy=230592
-> Bitmap Index Scan on t_x_idx (cost=0.00..53.50 rows=5000 width=0) (actual time=105.962..105.962 rows=593708 loops=1)
Index Cond: (x ~ '666666'::text)
Planning time: 0.420 ms
Execution time: 18111.739 ms
(8 rows)
postgres=> explain analyze select * from t where x ~ '666';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on t (cost=54.75..18107.92 rows=5000 width=22) (actual time=102.813..17285.086 rows=593708 loops=1)
Recheck Cond: (x ~ '666'::text)
Rows Removed by Index Recheck: 35665143
Heap Blocks: exact=39454 lossy=230592
-> Bitmap Index Scan on t_x_idx (cost=0.00..53.50 rows=5000 width=0) (actual time=96.100..96.100 rows=593708 loops=1)
Index Cond: (x ~ '666'::text)
Planning time: 0.500 ms
Execution time: 17300.440 ms
(8 rows)
关于PostgreSQL 使用 pg_trgm 比全扫描慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57683799/
使用 C# (VS2008) 和 WIA - 扫描到 TIFF 格式; 当我在平板或文档进纸器上使用扫描仪扫描 1 页时,该方法执行没有任何问题。当我将多个表单加载到进纸器时,扫描第一页后执行停止(保
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
给定一个列表 :: [(Foo, Bar)] ,我想在 Bar 上执行 scanl1 s,但保留他们的 Foo “标签”。 IE。我想要一个类型为 :: [(a, b)] -> ([b] -> [c]
我有一个 HBase 表,我需要从多个范围获取结果。例如,我可能需要从不同范围获取数据,例如第 1-6 行、100-150..... 我知道对于每次扫描,我可以定义开始行和停止行。但是如果我有 6 个
我看到了这段代码。我是 C 语言的新手,所以请原谅。 while下面的循环将继续循环 if i = SIZE,则 == 是无关紧要的,因为它根本不会被执行。如果 i 小于 SIZE 那么 scanf(
这是一个关于编译过程的相当技术性的问题ABAP代码。 我知道有ABAP解析器和扫描器类实际上调用 C 内核函数来完成实际工作。然后就是代码补全事务的功能,该事务以 ABAP 列表或 XML 的形式返回
给定以下程序: int main(){ float x = non_det_float(); float y = NAN; if (isnan(y) && x == 1.0f){
我在工作中使用由供应商生成的二维码。实际上我需要通过网站手动记录所有这些项目。 QR 码包含所有这些数据,所以我想创建一个自动执行操作的应用。 例如,二维码表示“AAA|BBB|CCC|123”。我想
我有一个像这样的字符串:@"ololo width: 350px jijiji width:440px ... text=12... "我想将@"width: "之后的所有数字替换为280。所以在扫描
我在玩 scanf 时遇到了一个小问题……更具体地说,我想读取整个输入,然后忽略其余部分。让我告诉你我的意思: #include int main(void) { int number_of
我正在使用 matlab/octave 创建扫描/线性调频信号,我的结束信号似乎以错误的频率结束。我该如何修复它,以便信号以正确的频率结束。 PS:我不能在 Octave 音程中使用 chirp 命令
我正在寻找一个可以扫描 WiFi 网络并打印所有 SSID 的程序。我试过 scapy 但我失败了。我正在使用 pyCharm 编辑器。 我试过这段代码: from scapy.all import
概述 Linux 完全是用于大型服务器的最流行和最安全的操作系统之一。尽管它被广泛使用,但它仍然容易受到网络攻击。黑客以服务器为目标,窃取有价值的信息。所以迫切需要开发反黑客方法来应对安全漏洞和恶
如何获取我的 Git 存储库的某种统计信息? 我目前在 BitBucket 中托管 Git 存储库,想查找以下详细信息: 提交总数 使用过的编程语言 每种编程语言的总代码行数 您认为这可以实现吗?还是
我目前正在使用以下代码来扫描作为申请表的一部分上传的文件: $safe_path = escapeshellarg($dir . $file); $command = '/usr/bin/clamsc
我在存储库中有十几个项目。存储库结构如下所示: / ------- + project1 +------- trunk +------- tags +----
我正在使用 Dynamo DB 并想使用过滤器扫描一个表。例如,是否可以使用全局二级索引仅扫描表中的特定行? 最佳答案 这不可能!扫描始终针对基表中的所有行,当您扫描索引表作为响应时,您将仅获得该索引
我正在尝试从这里使用 SOLStumbler:Accessing & Using the MobileWiFi.framework扫描 wifi 网络。我知道苹果不支持这一点,但它是用于教育目的和实验
我知道 iPhone 蓝牙功能在 3.0 之前无法通过 SDK 访问,但是需要多长时间才能找到该区域的设备?它取决于该区域的设备数量吗?如果范围内有大约 5 个设备,扫描发现所有设备是否需要花费 30
我正在使用Elasticsearch 6.2,并且有一些查询可以分析大量文档。我正在对索引内的一个字段进行排序。 Elasticsearch检查10.000个文档(默认配置值),然后将它们分页返回。
我是一名优秀的程序员,十分优秀!