关于SQL调优的几种方式,当然要看情况使用。结合自己的表结构和自己使用到的查询条件,使用最佳的优化方式。
局部索引(partial indexs)
假设我们经常使用特性过滤查询,而这种特性只存在个别行之中,我们就可以是使用partial indexs。 例如以下查询:
EXPLAIN ANALYZE SELECT id from tags WHERE name LIKE 'snow%' ORDER BY media_count DESC LIMIT 10;
QUERY PLAN
---------
Limit (cost=1780.73..1780.75 rows=10 width=32) (actual time=215.211..215.228 rows=10 loops=1)
-> Sort (cost=1780.73..1819.36 rows=15455 width=32) (actual time=215.209..215.215 rows=10 loops=1)
Sort Key: media_count
Sort Method: top-N heapsort Memory: 25kB
-> Index Scan using tags_search on tags_tag (cost=0.00..1446.75 rows=15455 width=32) (actual time=0.020..162.708 rows=64572 loops=1)
Index Cond: (((name)::text ~>=~ 'snow'::text) AND ((name)::text ~<~ 'snox'::text))
Filter: ((name)::text ~~ 'snow%'::text)
Total runtime: 215.275 ms
(8 rows)
注意Postgres必须对15,000行进行排序才能得到正确的结果。因为标签(例如)显示长尾模式,所以我们可以先尝试对超过100张照片的标签进行查询; 对超过100张照片的标签创建索引
CREATE INDEX CONCURRENTLY on tags (name text_pattern_ops)
WHERE media_count >= 100
建完索引之后再来看看执行计划,如下:
EXPLAIN ANALYZE SELECT * from tags WHERE name LIKE 'snow%' AND media_count >= 100 ORDER BY media_count DESC LIMIT 10;
QUERY PLAN
Limit (cost=224.73..224.75 rows=10 width=32) (actual time=3.088..3.105 rows=10 loops=1)
-> Sort (cost=224.73..225.15 rows=169 width=32) (actual time=3.086..3.090 rows=10 loops=1)
Sort Key: media_count
Sort Method: top-N heapsort Memory: 25kB
-> Index Scan using tags_tag_name_idx on tags_tag (cost=0.00..221.07 rows=169 width=32) (actual time=0.021..2.360 rows=924 loops=1)
Index Cond: (((name)::text ~>=~ 'snow'::text) AND ((name)::text ~<~ 'snox'::text))
Filter: ((name)::text ~~ 'snow%'::text)
Total runtime: 3.137 ms
(8 rows)
Postgres只需要访问169行,这要快得多。Postgres的查询规划器也非常擅长评估约束;如果您后来决定查询包含超过500张照片的标签,因为这些是这个索引的子集,所以它仍然使用正确的部分索引。
功能性索引 (Functional indexs)
在我们的一些表上,索引是非常长的字符串(例如,64个字符base64令牌),在这些字符串上创建索引最终会复制大量数据。对于这些,Postgres的功能索引功能非常有用
CREATE INDEX CONCURRENTLY on tokens (substr(token), 0, 8)
虽然会有多行匹配这个前缀,但是让Postgres匹配这些前缀然后过滤掉是非常快的,并且得到的索引的大小是为整个字符串建立索引的十分之一。
表重组使其数据紧凑 (pg_reorg For Compaction)
随着时间的推移,Postgres表可能在磁盘上被分割(例如,由于Postgres的MVCC并发模型)。而且,在大多数情况下,行插入顺序与希望返回行的顺序不匹配。例如,如果您经常查询由一个用户创建的所有like,那么将这些like放在磁盘上是有帮助的,这样可以最小化磁盘查找。 通过以下五个步骤,重组表。
1. 获取表的独占锁
2. 创建一个临时表来积累更改,并在原始表上添加一个触发器,该触发器将复制对这个临时表的任何更改
3. 使用SELECT FROM…ORDER BY创建表,它将在磁盘上按索引顺序创建一个新表
4. 同步SELECT from启动后临时表中的更改
5. 转换到新表。
自动模式和异步模式(Autocommit mode and async mode in psycopg2)
通过python pg的异步库可以实现异步访问postgress数据库.
1.Python 的 PostgreSQL 异步驱动 aiopg
2.asyncpg —— PostgresSQL 的开源Python 异步客户端开发包
相关链接
1. postgreSQl 批量执行sql的方式
2. Full Stack Python 系列之 5.5 PostgreSQL