我有一个DB“DB_One”,主表名为t_d_gate_out,上面有8个索引.我创建了另一个带有分区t_d_gate_out的数据库(我们称之为“DB_Two”).它按月和年分隔(子表的示例:t_d_gate_out09-2013),它有两个索引(每个子节点上的d_gate_out和新列:i_trx_own)
这是我创建和插入子表的功能:
CREATE OR REPLACE FUNCTION ctm_test.gateout_partition_function() RETURNS trigger AS $BODY$ DECLARE new_time text; tablename text; seqname text; seqname_schema text; bulantahun text; bulan text; bulan2 text; tahun text; enddate text; result record; BEGIN new_time := to_char(NEW.d_gate_out,'MM-YYYY'); bulan:=to_char(NEW.d_gate_out,'MM'); bulan2:=extract(month from NEW.d_gate_out); tahun:=to_char(NEW.d_gate_out,'YYYY'); bulantahun := new_time; tablename := 't_d_gate_out'||bulantahun; seqname := 't_d_gate_out'||bulantahun||'_seq'; seqname_schema := 'ctm_test.t_d_gate_out'||bulantahun||'_seq'; PERFORM 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind = 'r' AND c.relname = tablename AND n.nspname = 'ctm_test'; IF NOT FOUND THEN EXECUTE 'CREATE TABLE ctm_test.' || quote_ident(tablename) || ' ( i_trx_own serial PRIMARY KEY,CHECK (extract(month from d_gate_out)=' || bulan2 || ' AND extract(year from d_gate_out)=' || tahun || ')) INHERITS (ctm_test.t_d_gate_out)'; EXECUTE 'ALTER TABLE ctm_test.' || quote_ident(tablename) || ' OWNER TO postgres'; EXECUTE 'GRANT ALL ON TABLE ctm_test.' || quote_ident(tablename) || ' TO postgres'; EXECUTE 'CREATE INDEX ' || quote_ident(tablename||'_indx1') || ' ON ctm_test.' || quote_ident (tablename) || ' (i_trx_own);CREATE INDEX ' || quote_ident(tablename||'_indx2') || ' ON ctm_test.' || quote_ident (tablename) || ' (d_gate_out)'; END IF; EXECUTE 'INSERT INTO ctm_test.' || quote_ident(tablename) || ' VALUES ($1.*)' USING NEW; RETURN NULL; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; ALTER FUNCTION ctm_test.gateout_partition_function() OWNER TO postgres;
这是我的TRIGGER:
CREATE TRIGGER gateout_master_trigger BEFORE INSERT ON ctm_test.t_d_gate_out FOR EACH ROW EXECUTE PROCEDURE ctm_test.gateout_partition_function();
在插入大约200k行之后,我试图比较这两个DB之间的数据查看速度.我用来比较的查询:
select * from ctm_test."t_d_gate_out" where d_gate_out BETWEEN '2013-10-01' AND '2013-10-31'
我尝试多次执行该查询后的结果,执行时间几乎相同.因此,分区表无法更快地查看数据.
我是否正确地进行了分区?
只要每个查询都可以使用索引,它们的执行几乎相同. (实际上,您应该在分区表上看到顺序扫描,因为您从中读取了所有行.)
通过索引访问很快(我希望位图索引扫描).单片表上的索引(更大)(并且还需要一个额外的前导列),这可能会挑战您的RAM大小,并且第一次运行将花费更多.但是只要索引驻留在RAM中并且你有足够的数量,你就不会注意到进一步的调用.在其他情况下,您可能从分区中获得更多利益.
通过索引访问很快(我希望位图索引扫描).单片表上的索引(更大)(并且还需要一个额外的前导列),这可能会挑战您的RAM大小,并且第一次运行将花费更多.但是只要索引驻留在RAM中并且你有足够的数量,你就不会注意到进一步的调用.在其他情况下,您可能从分区中获得更多利益.
或者更糟糕的是:涉及多个分区的查询往往比单个大表上的等效查询慢.访问单个表会更便宜.通常情况下,不是像您所示的查询的情况:在较小的时间范围内,仅跨越一个(或几个)分区.最糟糕的情况是查询从整个范围读取行,随机展开.
如果您的表很大并且查询主要位于几个分区上,您可能会开始看到一个好处.小分区的索引要小得多,而且更容易适应RAM(并保留在那里).大量的RAM是性能的关键因素(除了匹配索引).
索引的数量几乎完全与读取性能无关.一般准则是尽可能少地创建索引,但需要尽可能多的索引.如果有疑问,支持简单的索引,这些索引可以针对高度专业化的索引提供更多种类的查询,针对单个用例量身定制(除非这种情况特别重要).任何未使用的索引只是写入性能的负担而浪费空间.
如果您最关心的是阅读性能,那么单个大桌上的partial indexes可能是另一种选择.
除此之外:您的触发功能可以在多个地方得到改善.从更易读的格式开始,这个提示:
> PL/pgSQL checking if a row exists – SELECT INTO boolean
带触发功能的相关答案:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。