① postgresql建了索引,查询用不上怎么回事
问题源自一个帅哥在建索引发生表锁的问题。先介绍一下Postgresql的建索引语法:
Version:9.1
CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ name ] ON table [ USING method ]
( { column | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
[ WITH ( storage_parameter = value [, ... ] ) ]
[ TABLESPACE tablespace ]
[ WHERE predicate ]
这里不解释语法的诸多参数使用(排序,使用方法,填充因子等),主要说一下concurrently的使用场景。
② postgresql 怎么创建位图索引
sysbench原来自带的lua数据装载脚本是使用以下方式串行装载的,速度比较慢(比单条insert快,但是比COPY慢)。insertintotable1values(),(),().insertintotable2values(),(),().insertintotablenvalues(),(),().使用prepare导入数据的用法举例./sy.
③ postgres怎么在线创建索引
我们知道数据库创建索引可能会锁住创建索引的表,并且用该表上的一次扫描来执行整个索引的构建,这样在创建索引时会影响在线业务,非常大的表创建索引可能会需要几个小时,这样阻塞业务是不被允许的。商业数据库一般都提供在线创建索引的能力,PostgreSQL作为开源数据库,也提供了这样的功能。我们在CREATE INDEX命令中新增CONCURRENTLY选项来实现索引的在线创建。 但是concurrently在线创建索引也并不是那么完美,当使用这个选项时,PostgreSQL必须执行该表的两次扫描,此外它必须等待所有现有可能会修改或者使用该索引的事务终止,甚至它可能会等待一个不相干的事务终止。因此这种方法比起普通的索引创建过程来说要做更多工作并且需要更多时间。同时,索引的创建会带来较大的CPU和I/O消耗。甚至在极端情况下,如果数据库存在长事务,我们发现create index命令根本无法结束。 从官方文档中我们可以了解到如下信息,在并发(concurrently)索引构建中,索引实际上是在事务中被构建的,它在两个事务中发生两次表扫描。在每一次表扫描之前,索引构建必须等待对该表做过修改的现有事务终止。在第二次扫描之后,索引构建必须等待任何持有早于第二次扫描的快照的事务终止。然后该索引最终能被标记为可用,CREATE INDEX命令完成。
开启第一个事务,拿到当前快照snapshot
2.等待所有修改过该表的事务结束
3.扫描该表,第一次创建索引
4.结束第一个事务
5.开启第二个事务,拿到当前快照snapshot2
6.等待所有修改过该表的事务结束
7.第二次扫描该表,将两次快照之间变更的记录,合并到索引
8.上一步更新索引结束后,等待snapshot2之前开启的所有事务结束
9.结束索引创建,索引变为可用 那么这里有个疑问,为什么需要两次扫描、两次创建索引?其实想想也很好解释。因为在第一次创建索引的时候不阻塞读写,这段时间内发生的变更需要在第二次扫描的时候合并更新进索引。
④ postgresql 怎么添加聚合索引
sysbench原来自带的lua数据装载脚本是使用以下方式串行装载的,速度比较慢(比单条insert快,但是比COPY慢)。insertintotable1values(),(),().insertintotable2values(),(),().insertintotablenvalues(),(),().使用prepare导入数据的用法举例./sysbench_pg--test=lua/oltp.lua--db-driver=pgsql--pgsql-host=127.0.0.1--pgsql-port=1921--pgsql-user=postgres--pgsql-password=postgres--pgsql-db=postgres--oltp-tables-count=64--oltp-table-size=1000000--num-threads=64prepareprepare表示装载数据,但是它串行的。sysbench0.5中可以在命令行中指定测试时启动的并行线程数,这个测试过程是使用run命令,而且是多线程并发的,所以我们可以使用sysbench的run命令来造数据,而不再使用其提供的prepare命令的方法来造数据。run命令会根据命令行参数--num-threads来指定并发线程数的多少。在sysbench中自定义的lua脚本中要求实现以下几个函数:functionthread_init(thread_id):此函数在线程创建后只被执行一次functionevent(thread_id):每执行一次就会被调用一次。由上可以知道,本次造数据的脚本我们只需要实现thread_init()函数就可以了。生成测试数据的脚本沿用老唐提供的代码:#include#include#include#include#includeuint64_tmy_rand(structrandom_data*r1,structrandom_data*r2){uint64_trand_max=100000000000LL;uint64_tresult;uint32_tu1,u2;random_r(r1,&u1);random_r(r2,&u2);result=(int64_t)u1*(int64_t)u2;result=result%rand_max;returnresult;}intmain(intargc,char*argv[]){structtimevaltpstart;structrandom_datar1,r2;inti;intr;intmax_value;charrand_state1[128];charrand_state2[128];if(argc!=2){printf("Usage:%s\n",argv[0]);return1;}max_value=atoi(argv[1]);gettimeofday(&tpstart,NULL);initstate_r(tpstart.tv_usec,rand_state1,sizeof(rand_state1),&r1);srandom_r(tpstart.tv_usec,&r1);gettimeofday(&tpstart,NULL);initstate_r(tpstart.tv_usec,rand_state2,sizeof(rand_state1),&r2);srandom_r(tpstart.tv_usec,&r2);for(i=1;i>sbtest'..table_id..'.dat&')os.execute('catsbtest'..table_id..'.dat|psql-h'..pgsql_host..'-p'..pgsql_port..'-U'..pgsql_user..'-d'..pgsql_db..'-c"sbtest'..table_id..'fromstdinwithcsv"')os.execute('rm-fsbtest'..table_id..'.dat')endfunctioncreate_index(table_id)db_query("selectsetval('sbtest"..table_id.."_id_seq',"..(oltp_table_size+1)..")")db_query("CREATEINDEXk_"..table_id.."onsbtest"..table_id.."(k)")endfunctionthread_init(thread_id)set_vars()print("threadprepare"..thread_id)fori=thread_id+1,oltp_tables_count,num_threadsdodata(i)create_index(i)endendfunctionevent(thread_id)os.exit()end用法,必须把psql放到路径中,因为lua中需要用到psql命令exportPATH=/home/digoal/pgsql9.5/bin:$PATH生成数据,速度比以前快多了./sysbench_pg--test=lua/.lua\--db-driver=pgsql\--pgsql-host=127.0.0.1\--pgsql-port=1921\--pgsql-user=postgres\--pgsql-password=postgres\--pgsql-db=postgres\--oltp-tables-count=64\--oltp-table-size=1000000\--num-threads=64\run清除数据,droptable./sysbench_pg--test=lua/.lua\--db-driver=pgsql\--pgsql-host=127.0.0.1\--pgsql-port=1921\--pgsql-user=postgres\--pgsql-password=postgres\--pgsql-db=postgres\--oltp-tables-count=64\--oltp-table-size=1000000\--num-threads=64\cleanuplua全局变量代码:sysbench/scripting/lua/src/lua.h:#definelua_register(L,n,f)(lua_pushcfunction(L,(f)),lua_setglobal(L,(n)))sysbench/scripting/lua/src/lua.h:#definelua_setglobal(L,s)lua_setfield(L,LUA_GLOBALSINDEX,(s))sysbench/scripting/lua/src/lbaselib.c:lua_setglobal(L,"_G");sysbench/scripting/lua/src/lbaselib.c:lua_setglobal(L,"_VERSION");/*setglobal_VERSION*/sysbench/scripting/lua/src/lbaselib.c:lua_setglobal(L,"newproxy");/*setglobal`newproxy'*/sysbench/scripting/script_lua.c:lua_setglobal(state,opt->name);sysbench/scripting/script_lua.c:lua_setglobal(state,"sb_rand");sysbench/scripting/script_lua.c:lua_setglobal(state,"sb_rand_uniq");sysbench/scripting/script_lua.c:lua_setglobal(state,"sb_rnd");sysbench/scripting/script_lua.c:lua_setglobal(state,"sb_rand_str");sysbench/scripting/script_lua.c:lua_setglobal(state,"sb_rand_uniform");sysbench/scripting/script_lua.c:lua_setglobal(state,"sb_rand_gaussian");sysbench/scripting/script_lua.c:lua_setglobal(state,"sb_rand_special");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_connect");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_disconnect");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_query");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_bulk_insert_init");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_bulk_insert_next");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_bulk_insert_done");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_prepare");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_bind_param");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_bind_result");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_execute");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_close");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_store_results");sysbench/scripting/script_lua.c:lua_setglobal(state,"db_free_results");sysbench/scripting/script_lua.c:lua_setglobal(state,"DB_ERROR_NONE");sysbench/scripting/script_lua.c:lua_setglobal(state,"DB_ERROR_DEADLOCK");sysbench/scripting/script_lua.c:lua_setglobal(state,"DB_ERROR_FAILED");sysbench/scripting/script_lua.c:lua_setglobal(L,"db_driver");传入参数,可以把sysbench_pg的参数-替换成_在lua脚本中使用这些变量,例子--pgsql-host=127.0.0.1->对应lua中的变量名pgsql_host--pgsql-port=1921->对应lua中的变量名pgsql_port--pgsql-user=postgres->对应lua中的变量名pgsql_user--pgsql-password=postgres->对应lua中的变量名pgsql_password--pgsql-db=postgres->对应lua中的变量名pgsql_db--oltp-tables-count=64->对应lua中的变量名oltp_tables_count--oltp-table-size=1000000->对应lua中的变量名oltp_table_size--num-threads=64->对应lua中的变量名num_threads
⑤ postgresql 数据库日期可以添加什么类型的索引
可以建立索引的;至于建立聚集索引或者是非聚集索引,那要看你这个时间字段的具体情况以及使用或变更频繁程度。 一般来说,适合建立聚集索引的要求:“既不能绝大多数都相同,又不能只有极少数相同”的规则。
⑥ pgadmin工具怎么创建索引
1、通过命令行查询 \d 数据库 —— 得到所有表的名字 \d 表名 —— 得到表结构 2、通过SQL语句查询 "select * from pg_tables" —— 得到当前db中所有表的信息(这里pg_tables是系统视图)
⑦ PG数据库不走索引
用以下sql就可以做到:
SELECT
schemaname = OBJECT_SCHEMA_NAME(o.object_id)
,tablename = o.NAME
FROM sys.objects o
INNER JOIN sys.indexes i ON i.OBJECT_ID = o.OBJECT_ID
WHERE (
o.type = 'U'
AND o.OBJECT_ID NOT IN (
SELECT OBJECT_ID
FROM sys.indexes
WHERE index_id > 0
)
)
⑧ PG里如何查看表,索引,表空间,数据库大小
--查询一个索引大小 select pg_size_pretty(pg_relation_size('indexname))--查看一张表及此它上的索引总大小 select pg_size_pretty(pg_total_relation_size('tablename')); --查看所有 schema里面索引大小,大到小的顺序排列: select indexrelname,pg_size_pretty( pg_relation_size(relid)) from pg_stat_user_indexes where schemaname = 'schemaname' order by pg_relation_size(relid) desc;--查看所有 schema里面表的大小,从大到小顺序排列: select relname, pg_size_pretty(pg_relation_size(relid)) from pg_stat_user_tables where schemaname = 'schemaname' order by pg_relation_size(relid) desc; --查看数据库大小: select pg_database.datname,pg_size_pretty(pg_database_size(pg_database.datname)) AS size from pg_database;--查看表空间大小
⑨ postgresql 查看表建立哪些索引
在数据库运维工作中,经常会有数据目录使用率较高需要调整的情况,通常会给数据库建立多个表空间,
并分别位于不同的盘上,这时需要做的工作就是调整库中现有表和索引的表空间,下面简单总结下这块维护
工作的内容,以下都是基于 PostgreSQL 9.0.1 做的测试。
一 查询某个表所在表空间的简单方法
PostgreSQL 提供类似" \ "命令很方便得到相关信息,命令如下:
skytf=> \d test_2
Table "skytf.test_2"
Column | Type | Modifiers
--------+-----------------------+-----------
id | integer |
obj_id | integer | not null
name | character varying(64) |
Indexes:
"idx_hash_name" hash (name)
"idx_test_2" btree (id, obj_id)
Tablespace: "tbs_skytf_idx"
备注:如果这个表的表空间为当前数据库的默认表空间,那么上面则不会显示 Tablespace 信息,
相反,则会显示这张有的表空间,例如上面的表 test_2 的表空间为 tbs_skytf_idx,而
表空间 "tbs_skytf_idx" 不是数据库 skytf 的默认表空间, 那么如何查询数据库的默认
表空间呢,可以通过以下命令查询。
--1.1 查询数据库的默认表空间
skytf=> select datname,dattablespace from pg_database where datname='skytf';
datname | dattablespace
---------+---------------
skytf | 14203070
(1 row)
skytf=> select oid,spcname from pg_tablespace where oid=14203070;
oid | spcname
----------+-----------
14203070 | tbs_skytf
(1 row)
备注:通过以上查出数据库 skytf 的默认表空间为 tbs_skytf。
二 批量查询数据库表和索引的表空间
--2.1 查询表和索引所在的表空间
select relname, relkind, relpages,pg_size_pretty(pg_relation_size(a.oid)), tb.spcname
from pg_class a, pg_tablespace tb
where a.reltablespace = tb.oid
and a.relkind in ('r', 'i')
order by a.relpages desc;
备注:上面只取了部分结果,这个查询能够查询表和索引所处的表空间,但是有一点需要注意,这个查询
仅显示表空间不是数据库默认表空间的数据库对像,而我们通常需要查出位于数据库默认表空间的
对像,显然上面的查询不是我们想要的,接下来看另一个查询。
--2.2 查询位于默认数据库表空间的对像
select relname, relkind, relpages,pg_size_pretty(pg_relation_size(a.oid)),reltablespace,relowner
from pg_class a
where a.relkind in ('r', 'i')
and reltablespace='0'
order by a.relpages desc;
备注:这个查询加入限制条件 reltablespace='0',即可查找出位于当前数据库默认表空间的
数据库表和索引。 通常这才是我们想要的结果,接下来可以把部分表转移到其它表空间上去,转移
的方法可以用 "ALTER TABLE move tablespace "或者重建索引移表空间等方法,这里不详细介绍。
--2.3 查询在某个表空间上的对像
select relname, relkind, relpages,pg_size_pretty(pg_relation_size(a.oid)),reltablespace,relowner
from pg_class a, pg_tablespace tb
where a.relkind in ('r', 'i')
and a.reltablespace=tb.oid
and tb.spcname='tablespace_name'
order by a.relpages desc;
--2.4 手册上对于 pgclass 视图的 reltablespace 字段解释
The tablespace in which this relation is stored. If zero, the database is default tablespace is
implied. (Not meaningful if the relation has no on-disk file.)