আমাদের সিস্টেম প্রচুর ডেটা লিখায় (বিগ ডেটা সিস্টেমের ধরণের)। লেখার পারফরম্যান্স আমাদের প্রয়োজনের জন্য যথেষ্ট ভাল তবে পড়ার পারফরম্যান্সটি সত্যই খুব ধীর।
প্রাথমিক কী (সীমাবদ্ধতা) কাঠামোটি আমাদের সমস্ত সারণীর জন্য সমান:
timestamp(Timestamp) ; index(smallint) ; key(integer).
একটি সারণীতে কয়েক মিলিয়ন সারি, এমনকি কয়েক বিলিয়ন সারি থাকতে পারে এবং একটি পঠন অনুরোধ সাধারণত একটি নির্দিষ্ট সময়কালের (টাইমস্ট্যাম্প / সূচক) এবং ট্যাগের জন্য থাকে। প্রায় 200k লাইনের প্রত্যাবর্তনকারী একটি কোয়েরি থাকা সাধারণ common বর্তমানে, আমরা প্রতি সেকেন্ডে প্রায় 15 ক লাইন পড়তে পারি তবে আমাদের 10 গুণ দ্রুত হওয়া দরকার। এটি কি সম্ভব এবং যদি তাই হয় তবে কীভাবে?
দ্রষ্টব্য: পোস্টগ্রিএসকিউএল আমাদের সফ্টওয়্যারটির সাথে প্যাকেজড, তাই হার্ডওয়্যারটি একটি ক্লায়েন্ট থেকে অন্য ক্লায়েন্টের থেকে আলাদা।
এটি পরীক্ষার জন্য ব্যবহৃত একটি ভিএম। ভিএম এর হোস্টটি উইন্ডোজ সার্ভার 2008 আর 2 এক্স 64 যার 24.0 গিগাবাইট র্যাম রয়েছে।
সার্ভার স্পেস (ভার্চুয়াল মেশিন ভিএমওয়্যার)
Server 2008 R2 x64
2.00 GB of memory
Intel Xeon W3520 @ 2.67GHz (2 cores)
postgresql.conf
optimisations
shared_buffers = 512MB (default: 32MB)
effective_cache_size = 1024MB (default: 128MB)
checkpoint_segment = 32 (default: 3)
checkpoint_completion_target = 0.9 (default: 0.5)
default_statistics_target = 1000 (default: 100)
work_mem = 100MB (default: 1MB)
maintainance_work_mem = 256MB (default: 16MB)
সারণি সংজ্ঞা
CREATE TABLE "AnalogTransition"
(
"KeyTag" integer NOT NULL,
"Timestamp" timestamp with time zone NOT NULL,
"TimestampQuality" smallint,
"TimestampIndex" smallint NOT NULL,
"Value" numeric,
"Quality" boolean,
"QualityFlags" smallint,
"UpdateTimestamp" timestamp without time zone, -- (UTC)
CONSTRAINT "PK_AnalogTransition" PRIMARY KEY ("Timestamp" , "TimestampIndex" , "KeyTag" ),
CONSTRAINT "FK_AnalogTransition_Tag" FOREIGN KEY ("KeyTag")
REFERENCES "Tag" ("Key") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE,
autovacuum_enabled=true
);
প্রশ্ন
ক্যোয়ারীটি পিজিএডমিন 3 এ চালিত হতে প্রায় 30 সেকেন্ড সময় নেয়, তবে আমরা যদি সম্ভব হয় তবে 5 সেকেন্ডের নীচে একই ফল পেতে চাই।
SELECT
"AnalogTransition"."KeyTag",
"AnalogTransition"."Timestamp" AT TIME ZONE 'UTC',
"AnalogTransition"."TimestampQuality",
"AnalogTransition"."TimestampIndex",
"AnalogTransition"."Value",
"AnalogTransition"."Quality",
"AnalogTransition"."QualityFlags",
"AnalogTransition"."UpdateTimestamp"
FROM "AnalogTransition"
WHERE "AnalogTransition"."Timestamp" >= '2013-05-16 00:00:00.000' AND "AnalogTransition"."Timestamp" <= '2013-05-17 00:00:00.00' AND ("AnalogTransition"."KeyTag" = 56 OR "AnalogTransition"."KeyTag" = 57 OR "AnalogTransition"."KeyTag" = 58 OR "AnalogTransition"."KeyTag" = 59 OR "AnalogTransition"."KeyTag" = 60)
ORDER BY "AnalogTransition"."Timestamp" DESC, "AnalogTransition"."TimestampIndex" DESC
LIMIT 500000;
ব্যাখ্যা কর…
"Limit (cost=0.00..125668.31 rows=500000 width=33) (actual time=2.193..3241.319 rows=500000 loops=1)"
" Buffers: shared hit=190147"
" -> Index Scan Backward using "PK_AnalogTransition" on "AnalogTransition" (cost=0.00..389244.53 rows=1548698 width=33) (actual time=2.187..1893.283 rows=500000 loops=1)"
" Index Cond: (("Timestamp" >= '2013-05-16 01:00:00-04'::timestamp with time zone) AND ("Timestamp" <= '2013-05-16 15:00:00-04'::timestamp with time zone))"
" Filter: (("KeyTag" = 56) OR ("KeyTag" = 57) OR ("KeyTag" = 58) OR ("KeyTag" = 59) OR ("KeyTag" = 60))"
" Buffers: shared hit=190147"
"Total runtime: 3863.028 ms"
2 ব্যাখ্যা করুন
আমার সর্বশেষ পরীক্ষায়, আমার ডেটা নির্বাচন করতে 7 মিনিট সময় লেগেছে! নিচে দেখ:
"Limit (cost=0.00..313554.08 rows=250001 width=35) (actual time=0.040..410721.033 rows=250001 loops=1)"
" -> Index Scan using "PK_AnalogTransition" on "AnalogTransition" (cost=0.00..971400.46 rows=774511 width=35) (actual time=0.037..410088.960 rows=250001 loops=1)"
" Index Cond: (("Timestamp" >= '2013-05-22 20:00:00-04'::timestamp with time zone) AND ("Timestamp" <= '2013-05-24 20:00:00-04'::timestamp with time zone) AND ("KeyTag" = 16))"
"Total runtime: 411044.175 ms"