যেহেতু আমি একজন তরুণ বিকাশকারী এবং ডেটাবেসগুলি ব্যবহার করার ক্ষেত্রে সত্যই দক্ষ নই (পোস্টগ্রিসকিউএল ৯.৩) আমি এমন একটি প্রকল্প নিয়ে কিছু সমস্যার মুখোমুখি হয়েছি, যেখানে আমার সত্যিই সহায়তা প্রয়োজন।
আমার প্রকল্পটি ডিভাইসগুলি (1000 বা আরও বেশি ডিভাইস পর্যন্ত) থেকে ডেটা সংগ্রহ করার বিষয়ে, যেখানে প্রতিটি ডিভাইস প্রতি সেকেন্ডে একটি করে ডেটা ব্লক পাঠাচ্ছে, যা প্রতি ঘন্টা 3 মিলিয়ন সারি করে।
বর্তমানে আমি একটি বড় টেবিল পেয়েছি যেখানে আমি প্রতিটি ডিভাইসের আগত ডেটা সঞ্চয় করি:
CREATE TABLE data_block(
id bigserial
timestamp timestamp
mac bigint
)
যেহেতু একাধিক প্রকারের ডেটা একটি ডেটা ব্লক অন্তর্ভুক্ত করতে পারে (বা করতে পারে না), অন্য সারণী রয়েছে যা সারণিকে উল্লেখ করে data_block।
CREATE TABLE dataA(
data_block_id bigserial
data
CONSTRAINT fkey FOREIGN KEY (data_block_id) REFERENCES data_block(id);
);
CREATE TABLE dataB(...);
CREATE TABLE dataC(...);
CREATE INDEX index_dataA_block_id ON dataA (data_block_id DESC);
...
এটি সম্ভব যে একটি ডাটা_ব্লকটিতে 3x ডেটাএ, 1 এক্স ডেটাবি, তবে কোনও ডেটাসি নেই।
ডেটা কয়েক সপ্তাহের জন্য রাখা হবে, তাই আমি এই টেবিলটিতে 5 বিলিয়ন ডলার সারি রাখব। এই মুহুর্তে, আমার টেবিলে ~ 600 মিলিয়ন সারি রয়েছে এবং আমার প্রশ্নগুলি সত্যই দীর্ঘ সময় নেয়। তাই আমি সিদ্ধান্ত নিয়েছিলাম একটি সূচক তৈরি করব timestampএবংmac কারণ আমার নির্বাচিত বিবৃতিগুলি সর্বদা সময়ের সাথে এবং প্রায়শই সময় + ম্যাকের সাথেও অনুসন্ধান করে।
CREATE INDEX index_ts_mac ON data_block (timestamp DESC, mac);
... তবে আমার প্রশ্নগুলি এখনও যুগে যুগে গ্রহণ করে। উদাহরণস্বরূপ, আমি একদিন এবং একটি ম্যাকের জন্য ডেটা জিজ্ঞাসা করেছি:
SELECT * FROM data_block
WHERE timestamp>'2014-09-15'
AND timestamp<'2014-09-17'
AND mac=123456789
Index Scan using index_ts_mac on data_block (cost=0.57..957307.24 rows=315409 width=32) (actual time=39.849..334534.972 rows=285857 loops=1)
Index Cond: ((timestamp > '2014-09-14 00:00:00'::timestamp without time zone) AND (timestamp < '2014-09-16 00:00:00'::timestamp without time zone) AND (mac = 123456789))
Total runtime: 334642.078 ms
ক্যোয়ারী চালানোর আগে আমি একটি পূর্ণ শূন্যতা করেছি। একটি কোয়েরি <10 সিসি করার জন্য বড় টেবিলগুলির সাথে এই জাতীয় সমস্যা সমাধানের জন্য কি একটি দুর্দান্ত উপায় আছে?
আমি বিভাজন সম্পর্কে পড়েছি, তবে এটি আমার ডেটাএ, ডেটাবি, ডাটাসি রেফারেন্স দিয়ে ডেটা_ব্লক_আইডি নিয়ে কাজ করবে না? যদি এটি কোনওভাবে কাজ করে তবে আমি কি সময় বা ম্যাকের সাথে পার্টিশন তৈরি করব?
আমি আমার সূচকটি অন্য দিকে বদলেছি। প্রথম ম্যাক, তারপরে টাইমস্ট্যাম্প এবং এটি প্রচুর পারফরম্যান্স লাভ করে।
CREATE INDEX index_mac_ts ON data_block (mac, timestamp DESC);
তবে এখনও, অনুসন্ধানগুলি> 30 সেকেন্ড নেয়। বিশেষত যখন আমি LEFT JOINআমার ডেটা টেবিলগুলি দিয়ে একটি করি। এখানে EXPLAIN ANALYZEনতুন সূচকের প্রশ্নগুলির একটি:
EXPLAIN ANALYZE SELECT * FROM data_block WHERE mac = 123456789 AND timestamp < '2014-10-05 00:00:00' AND timestamp > '2014-10-04 00:00:00'
Bitmap Heap Scan on data_block (cost=1514.57..89137.07 rows=58667 width=28) (actual time=2420.842..32353.678 rows=51342 loops=1)
Recheck Cond: ((mac = 123456789) AND (timestamp < '2014-10-05 00:00:00'::timestamp without time zone) AND (timestamp > '2014-10-04 00:00:00'::timestamp without time zone))
-> Bitmap Index Scan on index_mac_ts (cost=0.00..1499.90 rows=58667 width=0) (actual time=2399.291..2399.291 rows=51342 loops=1)
Index Cond: ((mac = 123456789) AND (timestamp < '2014-10-05 00:00:00'::timestamp without time zone) AND (timestamp > '2014-10-04 00:00:00'::timestamp without time zone))
Total runtime: 32360.620 ms
দুর্ভাগ্যক্রমে আমার হার্ডওয়্যার কঠোরভাবে সীমাবদ্ধ। আমি একটি ইন্টেল i3-2100 @ 3.10Ghz, 4 জিবি র্যাম ব্যবহার করছি। আমার বর্তমান সেটিংস নিম্নলিখিত হিসাবে রয়েছে:
default_statistics_target = 100
maintenance_work_mem = 512MB
constraint_exclusion = on
checkpoint_completion_target = 0.9
effective_cache_size = 4GB
work_mem = 512MB
wal_buffers = 16MB
checkpoint_segments = 32
shared_buffers = 2GB
max_connections = 20
random_page_cost = 2