我有一个webapplication,它对postgresql视图执行大约33.000行的搜索。如果我单独尝试这个,大约需要1-2秒才能得到一个结果,这是我首先想到的。但后来我从微软下载了Web应用程序压力测试工具,以便对我的webapp进行一些加载。所以我首先尝试了10个并发“用户”。当测试运行并且我执行搜索时需要更长的时间,我必须等待大约10-20秒才能得到我的结果,这是不可接受的。因为我是洞洞数据库(Postgresql)的新手,所以我在过去的3-4天里读了很多,但是我无法让搜索性能更快。我更改了一些配置设置,如work_mem,shared_buffer等,但它没有变得更好。
所以我的问题是:任何人都可以给我提示我可以在我的配置或服务器上更改哪些内容可以获得更好的性能,而不仅仅是10个并发用户?
以下是有关服务器和视图的一些详细信息:
服务器(虚拟机):
3 GHZ Xeon
3 GB Ram
40 GB Harddrive
视图的Select语句如下所示:
SELECT my selects, ....
FROM tab1
JOIN tab2 ON tab1.index1 = tab2.index1
JOIN tab3 ON tab1.index0 = tab3.index0
JOIN tab4 ON tab1.index1 = tab4.index1;
我在每个index1和index0上设置索引。
Explain Analyze(使用默认的postgres.conf):
EXPLAIN ANALYZE SELECT * from view_myview;
Nested Loop (cost=0.90..29042.71 rows=49840 width=1803) (actual time=0.384..5380.477 rows=33620 loops=1)
-> Merge Join (cost=0.90..11740.81 rows=24403 width=1257) (actual time=0.263..2548.377 rows=22601 loops=1)
Merge Cond: (tab2.index1 = tab1.index1)
-> Merge Join (cost=0.00..7170.63 rows=15968 width=1251) (actual time=0.157..1225.752 rows=15968 loops=1)
Merge Cond: (tab2.index1 = tab4.index1)
-> Index Scan using tab2_index1_idx on tab2 (cost=0.00..3617.45 rows=15968 width=1025) (actual time=0.053..239.399 rows=15968 loops=1)
-> Index Scan using tab4_index1_idx on tab4 (cost=0.00..3310.83 rows=17103 width=226) (actual time=0.045..253.721 rows=17103 loops=1)
-> Index Scan using tab1_index1_0_idx on tab4 (cost=0.00..4226.13 rows=24403 width=50) (actual time=0.051..347.333 rows=24403 loops=1)
-> Index Scan using tab3_index0_idx on tab3 (cost=0.00..0.64 rows=2 width=568) (actual time=0.030..0.050 rows=1 loops=22601)
Index Cond: (tab3.index0 = tab1.index0)
Total runtime: 5814.165 ms
希望任何人都可以提供帮助,
尼科
答案 0 :(得分:1)
您是否每次都在阅读整个视图,而不进行任何过滤?如果这意味着你在应用程序中进行过滤,那么你真的应该把它们作为WHERE子句。如果您正在使用WHERE子句并且不在此处的帖子中包含它,那么您需要重新发布包含的内容: - )
如果你每次都在阅读整篇文章,那么是的,你可以做的并不是那么多。正如之前所评论的那样,增加你的shared_buffers以便一切都适合(它似乎是一个小型数据库)。
该计划确实看起来有点奇怪 - 究竟哪些配置参数已更改,以及更改?
答案 1 :(得分:0)
这是一个星型查询,但出于某种原因,PostgreSQL
决定在维度表之间使用MERGE JOIN
。
正在扫描tab1
,tab2
和tab4
上的整个索引的结果会使缓存变得混乱。
尝试增加shared_buffer
,以便所有三个索引适合那里。
另外,您能否发布以下查询的结果?
SELECT COUNT(*)
FROM tab2
JOIN tab4
ON tab2.index1 = tab4.index1
SELECT COUNT(*)
FROM tab2
JOIN tab4
ON tab2.index1 = tab4.index1
JOIN tab1
ON tab1.index1 = tab4.index1
SELECT COUNT(*)
FROM tab1
JOIN tab3
ON tab3.index0 = tab1.index0
SELECT COUNT(*)
FROM tab1
JOIN tab4
ON tab1.index1 = tab4.index1
SELECT COUNT(*)
FROM tab1
JOIN tab2
ON tab1.index1 = tab2.index1
答案 2 :(得分:0)
正如您所说,您在问题中显示的单个查询并不是真正的问题。
在解决问题之前,您必须检测到真正的问题。 “10个连接需要很长时间”是不够的。
解释你发布的分析是无用的 - 用WHERE条件显示真实的查询。 时间(在解释分析输出中)仅证明您的服务器此刻只是过载。 40k行查询的5秒时间? - 那真的很悲惨。
您需要检测消耗大多数服务器资源的查询。 要实现此目的,请使用pgfouine等工具执行工作负载统计信息。这需要一些时间,但值得。
在猜测之前,我还要看看你的系统统计数据(IO使用情况,内存,CPU)。
如果要成为生产服务器,请设置监控工具 - 如果还没有。我推荐munin,很容易在15分钟内启动并运行(为一些Linux发行版打包)。