【发布时间】:2015-10-20 01:42:41
【问题描述】:
我有一个 URL 表(域和页面)
URLs
-----
url_id
url
我有一个域名列表,我想看看它是否包含在 URLs 表中。
所以如果我的列表中有一个域: http://stackoverflow.com
我希望它匹配以下 URLs.url 记录:
https://stackoverflow.com/question/230479
https://stackoverflow.com/question/395872364
等
URL 表相当大,1000 万+,而且还会增长
我要测试的域名列表会在 1-10k 之间变化
目前我正在创建域列表的临时表,然后加入 URLs 表以查找所有匹配的 URL
SELECT * from URLs
JOIN tmp_table_domains on tmp_table_domain.domain like URLs.url || '%'
我已经为 URLs.url 和 tmp_table_domain.domain 编制了索引,并认为索引将起作用,因为通配符在右侧。
但是,EXPLAIN ANALYZE 不显示正在使用的任何索引。一篇旧帖子提到 postgres 8.x 不能像加入索引一样,但我找不到其他支持或替代方案,或者它是否适用于较新版本
如果有帮助,我的 postgres 是 9.1。如果升级可以解决这个问题,那很好,唯一没有升级的原因并不是我所知道的任何原因
编辑_1 这是第一个数据库项目,我正在学习这一切
我不介意删除以上所有内容并使用更好的方法,无论是临时表/数组/更好的查询
edit_2
GroupAggregate (cost=1429152.90..1435118.48 rows=340890 width=44) (actual time=157905.450..157905.609 rows=27 loops=1)
-> Sort (cost=1429152.90..1430005.13 rows=340890 width=44) (actual time=157905.425..157905.451 rows=29 loops=1)
Sort Key: task_items.task_item
Sort Method: quicksort Memory: 29kB
-> Nested Loop (cost=14210.95..1387337.41 rows=340890 width=44) (actual time=18216.187..157905.055 rows=29 loops=1)
Join Filter: ((task_items.task_item)::text ~~ ((tmp_domains.domain)::text || '%'::text))
-> Hash Join (cost=14210.95..194126.53 rows=14066 width=44) (actual time=452.262..7953.639 rows=13737 loops=1)
Hash Cond: (task_items.task_id = tasks.task_id)
-> Seq Scan on task_items (cost=0.00..170062.71 rows=2589924 width=48) (actual time=0.019..4480.360 rows=2575206 loops=1)
Filter: (task_item_status_id = 2)
-> Hash (cost=14205.68..14205.68 rows=421 width=4) (actual time=440.409..440.409 rows=171 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 7kB
-> Seq Scan on tasks (cost=0.00..14205.68 rows=421 width=4) (actual time=101.491..439.821 rows=171 loops=1)
Filter: ((account_detail_id = 695) AND (base_action_type_id <> ALL ('{1,3,4}'::integer[])))
-> Materialize (cost=0.00..109.70 rows=4847 width=32) (actual time=0.002..4.924 rows=4536 loops=13737)
-> Seq Scan on tmp_domains (cost=0.00..85.47 rows=4847 width=32) (actual time=0.010..5.851 rows=4536 loops=1)
Total runtime: 157907.403 ms
实际查询与上面的简化解释有点不同。
task_items 的行数不到 700 万行 并且 tmp_domains 有 4,500
tl;博士
总结一下。将字符串列表部分匹配到列的最佳方法是什么
【问题讨论】:
-
但为什么是临时表?请务必发布您的解释输出
-
因为我真的不知道我在做什么和在各种事情上进行黑客攻击,这是目前我拥有的最好的 :-) 在它只是一个大的 WHERE url LIKE 'domain1.com%' 之前'domain2.com%' 或 ...'domain9999.com%'
-
您的 tmp 域表的内容来自哪里?
-
它通过消息队列来自外部进程。基本上我有一个接收列表的python函数,我想找到所有匹配它的现有项目
-
添加了解释分析输出。实际查询与最初所说的简化版本有点不同,唯一的主要区别是 task_items 是 URLs 表