There are too many different topics in one question, and even after many updates not all is clear. I'll just pick the elephant in th room and ignore the rest:
Query 1
-> Index Scan using r_pkey_index on relationships r (cost=0.43..57.53 rows=13 width=0)
(actual rows=1 loops=1)
Index Cond: (id = 947367::bigint)
Filter: ((date >= '2010-02-09'::date) AND (date <= '2010-11-24'::date))
Query 2
Filter: ((date >= '2010-02-09'::date) AND (date <= '2010-11-24'::date))
Rows Removed by Filter: 44104
-> Bitmap Index Scan on e_pkey_index (cost=0.00..4652.34 rows=251720 width=0)
(actual rows=263818 loops=1)
Index Cond: (id = 879::bigint)
Obviously, a single row matches your criteria in the first query, while there are more than 200.000 in the second. Obviously, the first can be much faster.
Leaving aside that we are comparing two queries on two different tables.
I have 3 solutions for you:
Direct reference of sequence and using concat
One possible solution is to reference the seqence in insert statement directly and prepend your node-id. A similar question including answer you can find here:
https://stackoverflow.com/a/17925601/4206293
Using a UUID
Another possible solution is, if you don't need you node-id in the primary-key field, you can use the uuid-ossp extension which provides the type uuid and the functions to generate uuids: http://www.postgresql.org/docs/9.4/static/uuid-ossp.html
Use a trigger for these solutions
For both solutions: you can use a trigger to set the primary key.
Example:
-- table
CREATE TABLE test(
id character varying(10) NOT NULL,
"name" character varying,
CONSTRAINT idx_pk PRIMARY KEY (id)
);
-- seqence
CREATE SEQUENCE test_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- Create Function
CREATE OR REPLACE FUNCTION insert_trigger()
RETURNS TRIGGER
AS $$
BEGIN
NEW.id := '100' || nextval('test_seq')::TEXT;
RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';
-- add Trigger
CREATE TRIGGER insert_table_trigger
BEFORE INSERT ON pkTable
FOR EACH ROW EXECUTE PROCEDURE insert_trigger();
If you now insert a value in the table
INSERT INTO test (name) VALUES ('test text');
you get your primary key '1001'
Using MINVALUE and MAXVALUE
Another way is you use the MINVALUE and MAXVALUE of SEQUENCE to define an numeric space:
CREATE SEQUENCE node100_seq
INCREMENT 1
MINVALUE 100000000000
MAXVALUE 100999999999
START 100000000000
CACHE 1;
CREATE SEQUENCE node200_seq
INCREMENT 1
MINVALUE 200000000000
MAXVALUE 200999999999
START 200000000000
CACHE 1;
Best Answer
i would not see this as a major issue. of course things are a little larger but if we talk about a single integer column things will most likely be lost in noise anyway. we got 24 bytes of tuple header ... then comes the data. if things are 4 bytes larger? what difference does it make in a 10 column table.
so, no worries ... make sure that you do what is good for your app.