বড় টেবিলের মধ্যে ধীর সূচক স্ক্যানগুলি


12

PostgreSQL 9.2 ব্যবহার করে, আমার তুলনামূলকভাবে বড় টেবিলের (200+ মিলিয়ন সারি) ধীর প্রশ্নগুলির সাথে ঝামেলা আছে। আমি ক্রেজি কিছু চেষ্টা করছি না, কেবল historicতিহাসিক মান যুক্ত করছি। নীচে কোয়েরি এবং ক্যোয়ারী প্ল্যান আউটপুট রয়েছে।

আমার টেবিল বিন্যাস:

                                   Table "public.energy_energyentry"
  Column   |           Type           |                            Modifiers
-----------+--------------------------+-----------------------------------------------------------------
 id        | integer                  | not null default nextval('energy_energyentry_id_seq'::regclass)
 prop_id   | integer                  | not null
 timestamp | timestamp with time zone | not null
 value     | double precision         | not null
Indexes:
    "energy_energyentry_pkey" PRIMARY KEY, btree (id)
    "energy_energyentry_prop_id" btree (prop_id)
    "energy_energyentry_prop_id_timestamp_idx" btree (prop_id, "timestamp")
Foreign-key constraints:
    "energy_energyentry_prop_id_fkey" FOREIGN KEY (prop_id) REFERENCES gateway_peripheralproperty(id) DEFERRABLE INITIALLY DEFERRED

2012-01-01 থেকে এখন অবধি ডেটা রয়েছে, প্রতিনিয়ত নতুন ডেটা যুক্ত করা হচ্ছে। prop_idবিদেশী কীতে প্রায় 2.2k স্বতন্ত্র মান রয়েছে , সমানভাবে বিতরণ করা হয়।

আমি লক্ষ্য করেছি যে সারিটির প্রাক্কলনগুলি খুব বেশি দূরে নয়, তবে ব্যয়ের অনুমান 4x ফ্যাক্টর দ্বারা বড় বলে মনে হচ্ছে। এটি সম্ভবত কোনও সমস্যা নয়, তবে এটি সম্পর্কে আমি কি কিছু করতে পারি?

আমি আশা করি যে ডিস্ক অ্যাক্সেস সমস্যা হতে পারে, যেহেতু টেবিলটি সর্বদা স্মৃতিতে থাকে না।

EXPLAIN ANALYZE 
SELECT SUM("value") 
FROM "energy_energyentry" 
WHERE 
  "prop_id"=82411 
  AND "timestamp">'2014-06-11' 
  AND "timestamp"<'2014-11-11'
;
 Aggregate  (cost=214481.45..214481.46 rows=1 width=8) (actual time=51504.814..51504.814 rows=1 loops=1)
   ->  Index Scan using energy_energyentry_prop_id_timestamp_idx on  energy_energyentry (cost=0.00..214434.08 rows=18947 width=8) (actual time=136.030..51488.321 rows=13578 loops=1)
         Index Cond: ((prop_id = 82411) AND ("timestamp" > '2014-06-11 00:00:00+00'::timestamp with time zone) AND ("timestamp" < '2014-11-11 00:00:00+00'::timestamp with time zone))
 Total runtime: 51504.841 ms

এটি কীভাবে দ্রুত করা যায় তার কোনও পরামর্শ?
আমি ঠিক শুনেছি আমি অদ্ভুত কিছু করি নি।


1
আপনার টেবিলটি কেমন দেখাচ্ছে, কী সূচি রয়েছে এবং ডেটা ছড়িয়ে রয়েছে তা দয়া করে আমাদের বলুন।
কলিন টি হার্ট

আপনার জিজ্ঞাসা করা অতিরিক্ত তথ্য আমি যুক্ত করেছি। আমি কিছু মিস করেছি কিনা ডুনো।
এক্সিলিয়ান

2
অদ্ভুত: আপনার ব্যাখ্যা বিশ্লেষণ শো prop_time_idx, তবুও সারণির সংজ্ঞা দেখায় entry_prop_id_timestamp_idx। এটি কি একই সূচক? ঠিক করুন
কলিন টি হার্ট

আপনার দ্বারা পড়ুন তাহলে সত্য যে করতে 'খরচ অনুমান একটি ফ্যাক্টর 4x বৃহত্তর হবে বলে মনে হচ্ছে' খরচ সংখ্যার ঐ 4 বার চলেছেন প্রকৃত সময় , তারপর নোটিশ খুশি যে দুটি একে অপরের সাথে কিছুই করার আছে। ব্যয়টি কেবলমাত্র একটি অনুমান, ক্যোয়ারী অপ্টিমাইজারকে সর্বাধিক সন্ধানী পরিকল্পনা চয়ন করতে সহায়তা করে। এই প্রসঙ্গে বাইরে, এটি সাধারণত অর্থহীন মান is
dezso

1
আপনার তারিখের পরিসীমা কতগুলি সারণী উপস্থাপন করে (এর মানগুলি বিবেচনা না করে prop)? যদি মাত্র একটি সামান্য শতাংশ, তবে একটি সূচক ("timestamp", prop)আরও ভাল হবে। একই নেতৃস্থানীয় কলাম (গুলি) সহ একাধিক সূচী ( propআপনার ক্ষেত্রে) এছাড়াও প্রায়শই নিষ্প্রয়োজন।
কলিন টি হার্ট

উত্তর:


10

আপনার টেবিলটি বড় এবং কোনও সারণি পুরো টেবিলটিতে বিস্তৃত। ধরে নিচ্ছি যে:

  • কেবলমাত্র নতুন ডেটা (সহ timestamp = now()) প্রবেশ করানো হয়েছে
  • বিদ্যমান সারিগুলি পরিবর্তন করা বা মোছা হয় না।
  • আপনার কাছে 2012-01-01 সাল থেকে ডেটা রয়েছে তবে ক্যোয়ারীগুলি মূলত বর্তমান বছরে (?)

আমি আংশিক, বহু-কলাম (আচ্ছাদন!) সূচকটি প্রস্তাব করব :

CREATE INDEX ON energy_energyentry (prop_id, "timestamp", value)
WHERE "timestamp" >= '2014-01-01 0:0';  -- adapt to your needs

কেবলমাত্র নিয়মিত জিজ্ঞাসিত সময়ের সীমা অন্তর্ভুক্ত করুন। নতুন এন্ট্রিগুলির সাথে সময়ের সাথে কার্যকারিতা খারাপ হয়। সূচি সময়ে সময়ে পুনরুদ্ধার করুন। (আপনার আপনার প্রশ্নের সমাধানের প্রয়োজন হতে পারে)) নীচে লিঙ্কিত উত্তর দেখুন।

এর বাইরে কেবলমাত্র সূচি-স্ক্যানগুলি পাওয়ার জন্য সর্বশেষ কলাম মানটি অন্তর্ভুক্ত । আক্রমনাত্মক autovacuum সেটিং দৃশ্যমানতা, আপ টু ডেট ম্যাপ রেখে সাহায্য করতে পারে @jjanes ইতিমধ্যে উল্লিখিত মত

আংশিক সূচকটি আরও সহজেই র‍্যামের সাথে ফিট করে এবং সেখানে আরও বেশি সময় থাকতে পারে stay

WHEREপরিকল্পনাকারীকে এই সূত্রটি ক্যোয়ারিতে প্রযোজ্য তা বোঝার জন্য আপনার এই শর্তটিকে প্রশ্নগুলির মধ্যে অন্তর্ভুক্ত করতে হবে :

SELECT sum(value) AS sum_value
FROM   energy_energyentry
WHERE  prop_id = 82411 
AND   "timestamp" > '2014-06-11 0:0' 
AND   "timestamp" < '2014-11-11 0:0'
AND   "timestamp" >= '2014-01-01 0:0'; -- seems redundant, but may be needed

যেহেতু আপনার ক্যোয়ারীতে প্রচুর সারি ( rows=13578) যোগ করা হচ্ছে, কেবলমাত্র সূচক-কেবল স্ক্যান করেও এটি কিছুটা সময় নিতে চলেছে। যদিও এটি 50 সেকেন্ডের কাছাকাছি হওয়া উচিত নয়। যে কোনও অর্ধপথের শালীন হার্ডওয়্যারটিতে এক সেকেন্ডেরও কম।

সম্পর্কিত (তবে অগ্রাহ্য করুন CLUSTERএবং FILLFACTOR, উভয়ই অপ্রাসঙ্গিক তবে যদি আপনি এর থেকে কেবল সূচি-স্ক্যান পেতে পারেন) :

অন্যদিকে:
যেহেতু আপনার বর্তমানে একটি সূচক চালু আছে (prop_id, "timestamp"), কেবলমাত্র অতিরিক্ত সূচকটি (prop_id)এর মূল্য ব্যয় করতে পারে:


এখন যে পোস্টগ্র্রেস ব্রিন সূচকে সমর্থন করে, তা কি এখানে কার্যকর হবে? পোস্টগ্রিজের ডেটাতে প্রায় ১৪০ মিলিয়ন সারি স্টোর করার পরিকল্পনা করছি, বড় টেবিলের জন্য ব্রিন কি সঠিক সূচক ব্যবহার করতে পারে?
আর্য

2

যদি আপনি সূচিটি তৈরি করেন (প্রোপ_আইডি, "টাইমস্ট্যাম্প", "মান"), তবে এটি কোনও টেবিলে না গিয়ে মান গণনা করতে কেবল সূচি-স্ক্যান ব্যবহার করতে পারে। এটি প্রচুর এলোমেলো ডিস্ক অ্যাক্সেস সঞ্চয় করতে পারে।

সর্বাধিক সুবিধা পেতে, আপনাকে টেবিলটি শূন্য করার বিষয়ে আক্রমণাত্মক হওয়া দরকার। ডিফল্ট অটোভ্যাক সেটিংস কেবলমাত্র সন্নিবেশ সারণীর জন্য যথেষ্ট আক্রমণাত্মক নয় যার উপর আপনি কেবলমাত্র সূচক-কেবলমাত্র স্ক্যানগুলি দক্ষতার সাথে সমর্থন করতে চান।


মানটি যুক্ত করা সত্যই আকর্ষণীয় হতে পারে, আমি এটি একবারে দেখব যা এটির গতি বাড়িয়ে দেবে কিনা। ভ্যাকুয়াম সেটিংস বা ডকুমেন্টেশনগুলির জন্য আমি কী দেখতে পারি তার জন্য আপনার কোনও পরামর্শ আছে?
এক্সিলিয়ান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.