col*_*mbo 5 sql postgresql indexing configuration
我一直在尝试在Windows Server 2012上的Azure VM上运行postgres 9.3.我最初在7GB服务器上运行它...我现在在14GB Azure VM上运行它.在尝试解决下面描述的问题时,我增加了一个尺寸.
顺便说一句,我对posgresql很新,所以我只是逐点了解配置选项.此外,虽然我喜欢在Linux上运行它,但我和我的同事根本没有专业知识来解决Linux中出现问题时的问题,因此Windows是我们唯一的选择.
问题描述:
我有一个名为test_table的表; 它目前存储大约9000万行.它将每月增长约3-4百万行.test_table中有2列:
id (bigserial)
url (charachter varying 300)
Run Code Online (Sandbox Code Playgroud)
我从几个CSV文件导入数据后创建了索引.两列都被编入索引.... id是主键.url上的索引是使用默认值通过pgAdmin创建的普通btree.
我跑的时候:
SELECT sum(((relpages*8)/1024)) as MB FROM pg_class WHERE reltype=0;
Run Code Online (Sandbox Code Playgroud)
...总大小为5980MB
这里讨论的2个索引的单个大小如下,我通过运行得到它们:
# SELECT relname, ((relpages*8)/1024) as MB, reltype FROM pg_class WHERE
reltype=0 ORDER BY relpages DESC LIMIT 10;
relname | mb | reltype
----------------------------------+------+--------
test_url_idx | 3684 | 0
test_pk | 2161 | 0
Run Code Online (Sandbox Code Playgroud)
其他较小的表上还有其他索引,但它们很小(<5MB)....所以我在这里忽略了它们
使用url查询test_table时遇到的麻烦,特别是在搜索中使用通配符时,速度(或缺少速度).例如
select * from test_table where url like 'orange%' limit 20;
Run Code Online (Sandbox Code Playgroud)
...需要20-40秒才能运行.
对上面的运行说明分析给出了以下内容:
# explain analyze select * from test_table where
url like 'orange%' limit 20;
QUERY PLAN
-----------------------------------------------------------------
Limit (cost=0.00..4787.96 rows=20 width=57)
(actual time=0.304..1898.583 rows=20 loops=1)
-> Seq Scan on test_table (cost=0.00..2303247.60 rows=9621 width=57)
(actual time=0.302..1898
.542 rows=20 loops=1)
Filter: ((url)::text ~~ 'orange%'::text)
Rows Removed by Filter: 210286
Total runtime: 1898.650 ms
(5 rows)
Run Code Online (Sandbox Code Playgroud)
再举一个例子......这次是美国和.com之间的通配符....
# explain select * from test_table where url
like 'american%.com' limit 50;
QUERY PLAN
-------------------------------------------------------
Limit (cost=0.00..11969.90 rows=50 width=57)
-> Seq Scan on test_table (cost=0.00..2303247.60 rows=9621 width=57)
Filter: ((url)::text ~~ 'american%.com'::text)
(3 rows)
# explain analyze select * from test_table where url
like 'american%.com' limit 50;
QUERY PLAN
-----------------------------------------------------
Limit (cost=0.00..11969.90 rows=50 width=57)
(actual time=83.470..3035.696 rows=50 loops=1)
-> Seq Scan on test_table (cost=0.00..2303247.60 rows=9621 width=57)
(actual time=83.467..303
5.614 rows=50 loops=1)
Filter: ((url)::text ~~ 'american%.com'::text)
Rows Removed by Filter: 276142
Total runtime: 3035.774 ms
(5 rows)
Run Code Online (Sandbox Code Playgroud)
然后我从7GB到14GB的服务器.查询速度并不好.
对服务器的观察
postgresql.conf文件只有一些默认值的更改.请注意,我从以下博客文章中获取了一些建议:http://www.gabrielweinberg.com/blog/2011/05/postgresql.html.
对conf的更改:
shared_buffers = 512MB
checkpoint_segments = 10
Run Code Online (Sandbox Code Playgroud)
(我更改了checkpoint_segments,因为我在加载CSV文件时收到了很多警告......虽然生产数据库不会非常密集,所以如果需要,可以将其更改回3 ...)
cpu_index_tuple_cost = 0.0005
effective_cache_size = 10GB # recommendation in the blog post was 2GB...
Run Code Online (Sandbox Code Playgroud)
在服务器本身的任务管理器 - >性能选项卡中,以下可能是可以提供帮助的人的相关位:
CPU:很少超过2%(无论运行什么查询...当我导入6GB CSV文件时,它达到11%)
内存:1.5/14.0GB(11%)
关于记忆的更多细节:
问题
谢谢阅读.
这些seq扫描使您看起来analyze在导入数据后没有在桌面上运行.
http://www.postgresql.org/docs/current/static/sql-analyze.html
在正常操作期间,调度运行vacuum analyze是没有用的,因为autovacuum会定期启动.但是在执行大量写入时(例如在导入期间)这很重要.
在一个稍微相关的说明中,如果您需要在结束时而不是在开始时运行锚定查询,请参阅Pavel的PostgreSQL技巧站点上的这个反向索引提示,例如 like '%.com'
http://postgres.cz/wiki/PostgreSQL_SQL_Tricks_I#section_20
关于你的实际问题,要小心你喜欢的那篇文章中的一些建议充其量是可疑的.改变索引使用的成本通常是可疑的,禁用seq扫描是彻头彻尾的愚蠢.(有时,它是便宜SEQ扫描表比ITIS使用索引).
话虽如此:
analyze在导入之后.当然,为Postgres提供足够的记忆也会增加记忆的可能性,但要记住后面的观点.有关微调的进一步阅读,请参阅手册和:
http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server
关于架构的最后两个注释:
varchar(300)和varchar没有指定长度(或者text就此而言)之间的唯一区别是对长度的额外检查约束.如果你实际上并不需要数据来适应这个大小,而且除了习惯之外没有任何理由这样做,你的数据库插入和更新将通过摆脱该约束来更快地运行.| 归档时间: |
|
| 查看次数: |
6064 次 |
| 最近记录: |