পোস্টগ্র্রেএসকিউএল-এ জিআইএন সূচক ব্যবহার করার সময় বাছাইয়ের অর্ডার দিয়ে কীভাবে গতি বাড়ানো যায়?


13

আমার এই মত একটি টেবিল আছে:

CREATE TABLE products (
  id serial PRIMARY KEY, 
  category_ids integer[],
  published boolean NOT NULL,
  score integer NOT NULL,
  title varchar NOT NULL);

একটি পণ্য একাধিক বিভাগে অন্তর্ভুক্ত থাকতে পারে। category_idsকলামে সমস্ত পণ্যের বিভাগগুলির আইডির একটি তালিকা রয়েছে।

সাধারণ ক্যোয়ারী এর মতো দেখাচ্ছে (সর্বদা একক বিভাগের জন্য অনুসন্ধান করা হয়):

SELECT * FROM products WHERE published
  AND category_ids @> ARRAY[23465]
ORDER BY score DESC, title
LIMIT 20 OFFSET 8000;

এটির গতি বাড়ানোর জন্য আমি নিম্নলিখিত সূচকটি ব্যবহার করি:

CREATE INDEX idx_test1 ON products
  USING GIN (category_ids gin__int_ops) WHERE published;

এক বিভাগে অনেক বেশি পণ্য না থাকলে এই এক অনেক সাহায্য করে। এটি সেই বিভাগের সাথে সম্পর্কিত পণ্যগুলি দ্রুত ফিল্টার করে তবে তারপরে একটি বাছাই করা অপারেশন হয় যা কঠোর উপায়ে করতে হয় (সূচক ছাড়াই)।

btree_ginএগুলি আমাকে এক্সটেনশানটি ইনস্টল করে মাল্টি কলাম-জিআইএন সূচকটি এভাবে তৈরি করতে দেয়:

CREATE INDEX idx_test2 ON products USING GIN (
  category_ids gin__int_ops, score, title) WHERE published;

তবে পোস্টগ্রিস বাছাইয়ের জন্য এটি ব্যবহার করতে চায় না । এমনকি যখন আমি কোয়েরিতে DESCসুনির্দিষ্ট সরাতে চাই ।

টাস্কটি অনুকূল করার জন্য যে কোনও বিকল্প পন্থা অত্যন্ত স্বাগত।


অতিরিক্ত তথ্য:

  • ইনটারে এক্সটেনশান সহ পোস্টগ্রিএসকিউএল 9.4
  • পণ্যের মোট সংখ্যা বর্তমানে ২0০ কে, তবে উল্লেখযোগ্যভাবে বৃদ্ধি পাওয়ার প্রত্যাশা রয়েছে (১০ এম পর্যন্ত, এটি মাল্টি-টেন্যান্ট ই-কমার্স প্ল্যাটফর্ম)
  • ১.১০০০০ বিভাগ অনুসারে পণ্যগুলি (১০০ কে পর্যন্ত বেড়ে উঠতে পারে), গড়ে ১০০ এর নিচে থাকে তবে বিপুল সংখ্যক পণ্যযুক্ত বিভাগগুলিতে আরও অনেক অনুরোধ আকর্ষণ করার প্রবণতা রয়েছে

নিম্নলিখিত পরীক্ষার পরিকল্পনাটি ছোট পরীক্ষা পদ্ধতি থেকে প্রাপ্ত হয়েছিল (নির্বাচিত বিভাগে 4680 পণ্য, টেবিলের মোট 200k পণ্য):

Limit  (cost=948.99..948.99 rows=1 width=72) (actual time=82.330..82.341 rows=20 loops=1)
  ->  Sort  (cost=948.37..948.99 rows=245 width=72) (actual time=80.231..81.337 rows=4020 loops=1)
        Sort Key: score, title
        Sort Method: quicksort  Memory: 928kB
        ->  Bitmap Heap Scan on products  (cost=13.90..938.65 rows=245 width=72) (actual time=1.919..16.044 rows=4680 loops=1)
              Recheck Cond: ((category_ids @> '{292844}'::integer[]) AND published)
              Heap Blocks: exact=3441
              ->  Bitmap Index Scan on idx_test2  (cost=0.00..13.84 rows=245 width=0) (actual time=1.185..1.185 rows=4680 loops=1)
                    Index Cond: (category_ids @> '{292844}'::integer[])
Planning time: 0.202 ms
Execution time: 82.404 ms

নোট # 1 : 82 এমএস এটিকে ভয়ঙ্কর মনে হতে পারে না তবে এটি কারণ সারণি বাফার মেমরির সাথে ফিট করে। আমি একবার পণ্য সারণী থেকে সমস্ত কলাম নির্বাচন করি ( SELECT * FROM ...এবং বাস্তব জীবনে প্রায় 60 টি কলাম রয়েছে) এটি Sort Method: external merge Disk: 5696kBকার্যকর করার সময় দ্বিগুণ হয়। এবং এটি কেবল 4680 পণ্যগুলির জন্য।

ক্রিয়াকলাপ # 1 (নোট # 1 থেকে আসে): সাজানোর ক্রিয়াকলাপের মেমরি পদচিহ্ন হ্রাস করার জন্য এবং তাই এটির গতি কিছুটা বাড়ানোর জন্য প্রথমে পণ্য আইডিকে আনার, সাজানোর এবং সীমাবদ্ধ করা বুদ্ধিমানের কাজ হবে, তারপরে সম্পূর্ণ রেকর্ডগুলি আনুন:

SELECT * FROM products WHERE id IN (
  SELECT id FROM products WHERE published AND category_ids @> ARRAY[23465]
  ORDER BY score DESC, title LIMIT 20 OFFSET 8000
) ORDER BY score DESC, title;

Sort Method: quicksort Memory: 903kB4680 টি পণ্যের জন্য এটি আমাদের কাছে ফিরে আসে এবং ms 80 এমএস। এখনও পণ্যের সংখ্যা 100 কে বেড়ে গেলে ধীর হতে পারে।


এই পৃষ্ঠায়: hlinnaka.iki.fi/2014/03/28/… মন্তব্য আছে যে btree_gin বাছাইয়ের জন্য ব্যবহার করা যাবে না।
ম্লাদেন উজেলা্যাক

ঠিক আছে, আরও বিকল্পের অনুমতি দেওয়ার জন্য আমি শিরোনামটি পুনরায় জমা করেছি।
ইয়ারোস্লাভ স্টাভিনিচি

আপনি কি সর্বদা একটি বিভাগের জন্য অনুসন্ধান করছেন? এবং দয়া করে আরও কিছু মৌলিক তথ্য সরবরাহ করুন: পোস্টগ্রিজ সংস্করণ, কার্ডিনালিটিস, প্রতি বিভাগে সারি (মিনিট / গড় / সর্বোচ্চ)। পোস্টগ্রিস্কল-পারফরম্যান্সের জন্য ট্যাগ তথ্যের নির্দেশাবলী বিবেচনা করুন । এবং: scoreনুল হতে পারে তবে আপনি এখনও অনুসারে বাছাই করেছেন score DESC, তা নয় score DESC NULLS LAST। এক বা
অন্যটিকে

আমি অনুরোধ হিসাবে অতিরিক্ত তথ্য যুক্ত করেছি। আমি সর্বদা একক বিভাগের জন্য অনুসন্ধান করছি। এবং scoreআসলে নাল নয় - আমি সারণির সংজ্ঞা সংশোধন করেছি।
ইয়ারোস্লাভ স্টাভিনিচি

উত্তর:


10

আমি প্রচুর পরীক্ষা-নিরীক্ষা করেছি এবং আমার অনুসন্ধানগুলি এখানে রয়েছে।

জিন এবং বাছাই

জিআইএন সূচক বর্তমানে (9.4 সংস্করণ হিসাবে) ক্রম সরবরাহ করতে সহায়তা করতে পারে না

বর্তমানে পোস্টগ্রেএসকিউএল সমর্থিত সূচীগুলির মধ্যে কেবল বি-ট্রিই বাছাই করা আউটপুট তৈরি করতে পারে - অন্য সূচক প্রকারগুলি অনির্ধারিত, বাস্তবায়ন-নির্ভর ক্রমে মেলানো সারিগুলি প্রদান করে।

work_mem

থেকে ইশারা জন্য ধন্যবাদ ক্রিস এই কনফিগারেশন প্যারামিটার । এটি 4 এমবিতে ডিফল্ট হয় এবং আপনার রেকর্ডসেটটি বড় হওয়ার ক্ষেত্রে work_memযথাযথ মান বাড়ানো (থেকে পাওয়া যেতে পারে EXPLAIN ANALYSE) সাজানোর ক্রিয়াকলাপগুলিকে উল্লেখযোগ্যভাবে গতি বাড়িয়ে তুলতে পারে।

ALTER SYSTEM SET work_mem TO '32MB';

পরিবর্তন কার্যকর হওয়ার জন্য সার্ভারটি পুনরায় চালু করুন, তারপরে ডাবল চেক করুন:

SHOW work_mem;

মূল ক্যোয়ারী

আমি আমার ডাটাবেসটি 650 কে পণ্যের সাথে 40 কে পণ্য ধারণ করে এমন কিছু বিভাগে তৈরি করেছি। আমি ক্লজটি সরিয়ে ক্যোয়ারিকে কিছুটা সহজ করেছি published:

SELECT * FROM products WHERE category_ids @> ARRAY [248688]
ORDER BY score DESC, title LIMIT 10 OFFSET 30000;

Limit  (cost=2435.62..2435.62 rows=1 width=1390) (actual time=1141.254..1141.256 rows=10 loops=1)
  ->  Sort  (cost=2434.00..2435.62 rows=646 width=1390) (actual time=1115.706..1140.513 rows=30010 loops=1)
        Sort Key: score, title
        Sort Method: external merge  Disk: 29656kB
        ->  Bitmap Heap Scan on products  (cost=17.01..2403.85 rows=646 width=1390) (actual time=11.831..25.646 rows=41666 loops=1)
              Recheck Cond: (category_ids @> '{248688}'::integer[])
              Heap Blocks: exact=6471
              ->  Bitmap Index Scan on idx_products_category_ids_gin  (cost=0.00..16.85 rows=646 width=0) (actual time=10.140..10.140 rows=41666 loops=1)
                    Index Cond: (category_ids @> '{248688}'::integer[])
Planning time: 0.288 ms
Execution time: 1146.322 ms

যেহেতু আমরা দেখতে পাচ্ছি work_memযথেষ্ট ছিল না তাই আমাদের ছিল Sort Method: external merge Disk: 29656kB(এখানে নম্বরটি আনুমানিক, ইন-মেমরি কুইকোর্টের জন্য এটি 32MB এর চেয়ে কিছুটা বেশি বেশি প্রয়োজন)।

মেমরির পদচিহ্ন হ্রাস করুন

বাছাইয়ের জন্য সম্পূর্ণ রেকর্ড নির্বাচন করবেন না, আইডি ব্যবহার করুন, সাজান প্রয়োগ করুন, অফসেট এবং সীমাবদ্ধ করুন, তারপরে আমাদের প্রয়োজন মাত্র 10 টি রেকর্ড লোড করুন:

SELECT * FROM products WHERE id in (
  SELECT id FROM products WHERE category_ids @> ARRAY[248688]
  ORDER BY score DESC, title LIMIT 10 OFFSET 30000
) ORDER BY score DESC, title;

Sort  (cost=2444.10..2444.11 rows=1 width=1390) (actual time=707.861..707.862 rows=10 loops=1)
  Sort Key: products.score, products.title
  Sort Method: quicksort  Memory: 35kB
  ->  Nested Loop  (cost=2436.05..2444.09 rows=1 width=1390) (actual time=707.764..707.803 rows=10 loops=1)
        ->  HashAggregate  (cost=2435.63..2435.64 rows=1 width=4) (actual time=707.744..707.746 rows=10 loops=1)
              Group Key: products_1.id
              ->  Limit  (cost=2435.62..2435.62 rows=1 width=72) (actual time=707.732..707.734 rows=10 loops=1)
                    ->  Sort  (cost=2434.00..2435.62 rows=646 width=72) (actual time=704.163..706.955 rows=30010 loops=1)
                          Sort Key: products_1.score, products_1.title
                          Sort Method: quicksort  Memory: 7396kB
                          ->  Bitmap Heap Scan on products products_1  (cost=17.01..2403.85 rows=646 width=72) (actual time=11.587..35.076 rows=41666 loops=1)
                                Recheck Cond: (category_ids @> '{248688}'::integer[])
                                Heap Blocks: exact=6471
                                ->  Bitmap Index Scan on idx_products_category_ids_gin  (cost=0.00..16.85 rows=646 width=0) (actual time=9.883..9.883 rows=41666 loops=1)
                                      Index Cond: (category_ids @> '{248688}'::integer[])
        ->  Index Scan using products_pkey on products  (cost=0.42..8.45 rows=1 width=1390) (actual time=0.004..0.004 rows=1 loops=10)
              Index Cond: (id = products_1.id)
Planning time: 0.682 ms
Execution time: 707.973 ms

নোট Sort Method: quicksort Memory: 7396kB। ফলাফল আরও ভাল।

যোগদান করুন এবং অতিরিক্ত বি-ট্রি সূচি

ক্রিস পরামর্শ হিসাবে আমি অতিরিক্ত সূচক তৈরি করেছি:

CREATE INDEX idx_test7 ON products (score DESC, title);

প্রথমে আমি এইভাবে যোগদানের চেষ্টা করেছি:

SELECT * FROM products NATURAL JOIN
  (SELECT id FROM products WHERE category_ids @> ARRAY[248688]
  ORDER BY score DESC, title LIMIT 10 OFFSET 30000) c
ORDER BY score DESC, title;

অনুসন্ধান পরিকল্পনা কিছুটা পৃথক হলেও ফলাফল একই:

Sort  (cost=2444.10..2444.11 rows=1 width=1390) (actual time=700.747..700.747 rows=10 loops=1)
  Sort Key: products.score, products.title
  Sort Method: quicksort  Memory: 35kB
  ->  Nested Loop  (cost=2436.05..2444.09 rows=1 width=1390) (actual time=700.651..700.690 rows=10 loops=1)
        ->  HashAggregate  (cost=2435.63..2435.64 rows=1 width=4) (actual time=700.630..700.630 rows=10 loops=1)
              Group Key: products_1.id
              ->  Limit  (cost=2435.62..2435.62 rows=1 width=72) (actual time=700.619..700.619 rows=10 loops=1)
                    ->  Sort  (cost=2434.00..2435.62 rows=646 width=72) (actual time=697.304..699.868 rows=30010 loops=1)
                          Sort Key: products_1.score, products_1.title
                          Sort Method: quicksort  Memory: 7396kB
                          ->  Bitmap Heap Scan on products products_1  (cost=17.01..2403.85 rows=646 width=72) (actual time=10.796..32.258 rows=41666 loops=1)
                                Recheck Cond: (category_ids @> '{248688}'::integer[])
                                Heap Blocks: exact=6471
                                ->  Bitmap Index Scan on idx_products_category_ids_gin  (cost=0.00..16.85 rows=646 width=0) (actual time=9.234..9.234 rows=41666 loops=1)
                                      Index Cond: (category_ids @> '{248688}'::integer[])
        ->  Index Scan using products_pkey on products  (cost=0.42..8.45 rows=1 width=1390) (actual time=0.004..0.004 rows=1 loops=10)
              Index Cond: (id = products_1.id)
Planning time: 1.015 ms
Execution time: 700.918 ms

বিভিন্ন অফসেট এবং পণ্য সংখ্যা নিয়ে খেলতে পোস্টগ্র্রেএসকিউএল অতিরিক্ত বি-ট্রি সূচক ব্যবহার করতে পারি না।

সুতরাং আমি শাস্ত্রীয় পথে গিয়ে জংশন সারণী তৈরি করেছি :

CREATE TABLE prodcats AS SELECT id AS product_id, unnest(category_ids) AS category_id FROM products;
CREATE INDEX idx_prodcats_cat_prod_id ON prodcats (category_id, product_id);

SELECT p.* FROM products p JOIN prodcats c ON (p.id=c.product_id)
WHERE c.category_id=248688
ORDER BY p.score DESC, p.title LIMIT 10 OFFSET 30000;

Limit  (cost=122480.06..122480.09 rows=10 width=1390) (actual time=1290.360..1290.362 rows=10 loops=1)
  ->  Sort  (cost=122405.06..122509.00 rows=41574 width=1390) (actual time=1264.250..1289.575 rows=30010 loops=1)
        Sort Key: p.score, p.title
        Sort Method: external merge  Disk: 29656kB
        ->  Merge Join  (cost=50.46..94061.13 rows=41574 width=1390) (actual time=117.746..182.048 rows=41666 loops=1)
              Merge Cond: (p.id = c.product_id)
              ->  Index Scan using products_pkey on products p  (cost=0.42..90738.43 rows=646067 width=1390) (actual time=0.034..116.313 rows=210283 loops=1)
              ->  Index Only Scan using idx_prodcats_cat_prod_id on prodcats c  (cost=0.43..1187.98 rows=41574 width=4) (actual time=0.022..7.137 rows=41666 loops=1)
                    Index Cond: (category_id = 248688)
                    Heap Fetches: 0
Planning time: 0.873 ms
Execution time: 1294.826 ms

তবুও বি-ট্রি সূচকটি ব্যবহার করা হচ্ছে না, ফলাফলসেট ফিট হয় না, ফলস্বরূপ work_memখারাপ ফলাফল।

তবে কিছু পরিস্থিতিতে বিপুল সংখ্যক পণ্য এবং ছোট অফসেট পোস্টগ্রিএসকিউএল এখন বি-ট্রি সূচি ব্যবহার করার সিদ্ধান্ত নেয়:

SELECT p.* FROM products p JOIN prodcats c ON (p.id=c.product_id)
WHERE c.category_id=248688
ORDER BY p.score DESC, p.title LIMIT 10 OFFSET 300;

Limit  (cost=3986.65..4119.51 rows=10 width=1390) (actual time=264.176..264.574 rows=10 loops=1)
  ->  Nested Loop  (cost=0.98..552334.77 rows=41574 width=1390) (actual time=250.378..264.558 rows=310 loops=1)
        ->  Index Scan using idx_test7 on products p  (cost=0.55..194665.62 rows=646067 width=1390) (actual time=0.030..83.026 rows=108037 loops=1)
        ->  Index Only Scan using idx_prodcats_cat_prod_id on prodcats c  (cost=0.43..0.54 rows=1 width=4) (actual time=0.001..0.001 rows=0 loops=108037)
              Index Cond: ((category_id = 248688) AND (product_id = p.id))
              Heap Fetches: 0
Planning time: 0.585 ms
Execution time: 264.664 ms

এটি বাস্তবে যথেষ্ট যৌক্তিক কারণ এখানে বি-ট্রি সূচক সরাসরি ফলাফল দেয় না, এটি কেবল সিক্যুয়াল স্ক্যানের গাইড হিসাবে ব্যবহৃত হয়।

আসুন জিআইএন ক্যোয়ারির সাথে তুলনা করি:

SELECT * FROM products WHERE id in (
  SELECT id FROM products WHERE category_ids @> ARRAY[248688]
  ORDER BY score DESC, title LIMIT 10 OFFSET 300
) ORDER BY score DESC, title;

Sort  (cost=2519.53..2519.55 rows=10 width=1390) (actual time=143.809..143.809 rows=10 loops=1)
  Sort Key: products.score, products.title
  Sort Method: quicksort  Memory: 35kB
  ->  Nested Loop  (cost=2435.14..2519.36 rows=10 width=1390) (actual time=143.693..143.736 rows=10 loops=1)
        ->  HashAggregate  (cost=2434.71..2434.81 rows=10 width=4) (actual time=143.678..143.680 rows=10 loops=1)
              Group Key: products_1.id
              ->  Limit  (cost=2434.56..2434.59 rows=10 width=72) (actual time=143.668..143.670 rows=10 loops=1)
                    ->  Sort  (cost=2433.81..2435.43 rows=646 width=72) (actual time=143.642..143.653 rows=310 loops=1)
                          Sort Key: products_1.score, products_1.title
                          Sort Method: top-N heapsort  Memory: 68kB
                          ->  Bitmap Heap Scan on products products_1  (cost=17.01..2403.85 rows=646 width=72) (actual time=11.625..31.868 rows=41666 loops=1)
                                Recheck Cond: (category_ids @> '{248688}'::integer[])
                                Heap Blocks: exact=6471
                                ->  Bitmap Index Scan on idx_products_category_ids_gin  (cost=0.00..16.85 rows=646 width=0) (actual time=9.916..9.916 rows=41666 loops=1)
                                      Index Cond: (category_ids @> '{248688}'::integer[])
        ->  Index Scan using products_pkey on products  (cost=0.42..8.45 rows=1 width=1390) (actual time=0.004..0.004 rows=1 loops=10)
              Index Cond: (id = products_1.id)
Planning time: 0.630 ms
Execution time: 143.921 ms

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

বাস্তব সূচকের শক্তি

বাছাইয়ের জন্য পোস্টগ্রেএসকিউএলকে সূচকে সম্পূর্ণরূপে ব্যবহার করার জন্য, সমস্ত ক্যোয়ারী WHEREপ্যারামিটারগুলির পাশাপাশি ORDER BYপ্যারামিটারগুলি অবশ্যই একক বি-ট্রি সূচীতে থাকা উচিত। এটি করার জন্য আমি পণ্য থেকে জংশন সারণিতে সাজানোর ক্ষেত্রগুলি অনুলিপি করেছি:

CREATE TABLE prodcats AS SELECT id AS product_id, unnest(category_ids) AS category_id, score, title FROM products;
CREATE INDEX idx_prodcats_1 ON prodcats (category_id, score DESC, title, product_id);

SELECT * FROM products WHERE id in (SELECT product_id FROM prodcats WHERE category_id=248688 ORDER BY score DESC, title LIMIT 10 OFFSET 30000) ORDER BY score DESC, title;

Sort  (cost=2149.65..2149.67 rows=10 width=1390) (actual time=7.011..7.011 rows=10 loops=1)
  Sort Key: products.score, products.title
  Sort Method: quicksort  Memory: 35kB
  ->  Nested Loop  (cost=2065.26..2149.48 rows=10 width=1390) (actual time=6.916..6.950 rows=10 loops=1)
        ->  HashAggregate  (cost=2064.83..2064.93 rows=10 width=4) (actual time=6.902..6.904 rows=10 loops=1)
              Group Key: prodcats.product_id
              ->  Limit  (cost=2064.02..2064.71 rows=10 width=74) (actual time=6.893..6.895 rows=10 loops=1)
                    ->  Index Only Scan using idx_prodcats_1 on prodcats  (cost=0.56..2860.10 rows=41574 width=74) (actual time=0.010..6.173 rows=30010 loops=1)
                          Index Cond: (category_id = 248688)
                          Heap Fetches: 0
        ->  Index Scan using products_pkey on products  (cost=0.42..8.45 rows=1 width=1390) (actual time=0.003..0.003 rows=1 loops=10)
              Index Cond: (id = prodcats.product_id)
Planning time: 0.318 ms
Execution time: 7.066 ms

এবং এটি নির্বাচিত বিভাগ এবং বৃহত্তর অফসেটে প্রচুর সংখ্যক পণ্য সহ সবচেয়ে খারাপ পরিস্থিতি। অফসেট = 300 কার্যকর করার সময় মাত্র 0.5 এমএস।

দুর্ভাগ্যক্রমে এই জাতীয় জংশন সারণি বজায় রাখার জন্য অতিরিক্ত প্রচেষ্টা প্রয়োজন requires এটি সূচকযুক্ত বস্তুগত দৃশ্যের মাধ্যমে সম্পন্ন হতে পারে তবে এটি তখনই কার্যকর যখন আপনার ডেটা খুব কমই আপডেট হয়, কারণ এ জাতীয় বস্তুগত দৃষ্টিভঙ্গি সতেজ করা বেশ ভারী ক্রিয়াকলাপ।

সুতরাং আমি বর্ধিত work_memএবং হ্রাস মেমরির পদচিহ্ন ক্যোয়ারী সহ এখনও অবধি জিআইএন সূচক নিয়ে আছি ।


আপনাকে যা না প্রয়োজন পুনর্সূচনা সাধারণ পরিবর্তনের জন্য work_mempostgresql.conf মধ্যে সেটিং। পুনরায় লোড যথেষ্ট। এবং আমাকে work_memএকাধিক ব্যবহারকারীর পরিবেশে বিশ্বব্যাপী খুব উচ্চ স্থাপনের বিরুদ্ধে সতর্ক করতে দেওয়া (খুব কম নয়, হয় না)। আপনার যদি কিছু প্রশ্নের বেশি প্রয়োজন হয় work_memতবে অধিবেশনটির জন্য SET- বা কেবলমাত্র লেনদেন দিয়ে এটিকে উচ্চতর সেট করুন SET LOCAL। দেখুন: dba.stackexchange.com/a/48633/3684
এরউইন ব্র্যান্ডস্টেটার

কি দুর্দান্ত উত্তর। বিশেষত ডিস্ক দিয়ে আমাকে অনেক সহায়তা করেছে -> ইন-মেমোরি সাজানোর ক্রিয়াকলাপ, দুর্দান্ত জয়ের জন্য দ্রুত পরিবর্তন, ধন্যবাদ!
রিকার্ডো ভিলমিল

4

এখানে কয়েকটি দ্রুত টিপস যা আপনার কর্মক্ষমতা উন্নত করতে সহায়তা করতে পারে। আমি সহজতম টিপ দিয়ে শুরু করব, যা আপনার পক্ষে প্রায় অনায়াসেই, এবং প্রথমটির পরে আরও কঠিন টিপসটিতে চলে যাব।

1। work_mem

সুতরাং, আমি ডানদিকে দেখছি যে আপনার ব্যাখ্যা পরিকল্পনায় রিপোর্ট করা একটি সাজানো Sort Method: external merge Disk: 5696kB6 এমবি কম খরচ করছে, তবে ডিস্কে ছড়িয়ে দিচ্ছে। work_memআপনার postgresql.confফাইলটিতে আপনার সেটিংটি বাড়ানোর দরকার যাতে যথেষ্ট বাছাই করা যায় যাতে সাজানোর মেমরিটিতে ফিট হতে পারে।

সম্পাদনা: অধিকতর পরিদর্শন করার পরে, আমি দেখতে পাচ্ছি যে catgory_idsআপনার মানদণ্ডের সাথে মানানসই যাচাই করতে সূচি ব্যবহার করার পরে , বিটম্যাপ সূচক স্ক্যানটি "ক্ষয়ক্ষতি" হতে বাধ্য হয় এবং প্রাসঙ্গিক স্তূপ পৃষ্ঠাগুলি থেকে সারিগুলি পড়ার সময় শর্তটি পুনরায় পরীক্ষা করতে হয় has । আমার দেওয়া থেকে আরও ভাল ব্যাখ্যা করার জন্য এই পোস্টটি postgresql.org এ দেখুন। : পি মূল কথাটি আপনারwork_memউপায়টি খুব কম। আপনি যদি আপনার সার্ভারে ডিফল্ট সেটিংস টিউন না করে থাকেন তবে এটি ভাল সম্পাদন করবে না।

এই ফিক্সটি আপনাকে মূলত কোনও সময় নেবে না। একটি পরিবর্তন postgresql.conf, এবং আপনি বন্ধ! এটি উল্লেখ করুনআরও টিপসের জন্য পারফরম্যান্স টিউনিং পৃষ্ঠাটি দেখুন।

2. স্কিমা পরিবর্তন

সুতরাং, আপনি আপনার স্কিমা ডিজাইনে সিদ্ধান্তটি category_idsএকটি পূর্ণসংখ্যার অ্যারে হিসাবে সংজ্ঞায়িত করার সিদ্ধান্ত নিয়েছেন , যা আপনাকে দ্রুত অ্যাক্সেস পেতে একটি জিআইএন বা জিআইএসটি সূচক ব্যবহার করতে বাধ্য করে। আমার অভিজ্ঞতায়, আপনার জিআইএন সূচকের পছন্দ জিআইএসটির চেয়ে পড়ার পক্ষে দ্রুত হবে, সুতরাং সেই ক্ষেত্রে আপনি সঠিক পছন্দটি করেছেন। তবে, জিআইএন একটি অরসোর্টড সূচক; আরো একটি কী-মান, যেখানে সমতা predicates চেক করতে সহজ হয় মত মনে, কিন্তু অপারেশন যেমন WHERE >, WHERE <অথবাORDER BY সূচক দ্বারা সুগম নেই।

একটি শালীন দৃষ্টিভঙ্গি হ'ল ব্রিজ টেবিল / জংশন সারণী ব্যবহার করে আপনার নকশাটিকে সাধারণকরণ করা , যা ডাটাবেসে বহু থেকে বহু সম্পর্ক নির্দিষ্ট করতে ব্যবহৃত হয়।

এক্ষেত্রে আপনার অনেকগুলি বিভাগ এবং একইসংখ্যক পূর্ণসংখ্যার সমষ্টি রয়েছে category_idএবং আপনার অনেকগুলি পণ্য এবং তাদের সাথে সম্পর্কিত product_id। আপনার প্রোডাক্ট টেবিলের একটি কলামের পরিবর্তে যা এর পূর্ণসংখ্যা অ্যারে রয়েছে category_id, আপনার স্কিমা থেকে এই অ্যারে কলামটি সরিয়ে ফেলুন এবং একটি সারণী তৈরি করুন

CREATE TABLE join_products_categories (product_id int, category_id int);

তারপরে, আপনি ব্রিজ টেবিলের দুটি কলামে বি-ট্রি সূচকগুলি তৈরি করতে পারেন,

CREATE INDEX idx_products_in_join_table ON join_products_categories (product_id);
CREATE INDEX idx_products_in_join_table ON join_products_categories (category_id);

কেবল আমার নম্র মতামত, তবে এই পরিবর্তনগুলি আপনার জন্য একটি বড় পার্থক্য আনতে পারে। work_memখুব অল্প সময়ে, প্রথম পরিবর্তনটি চেষ্টা করে দেখুন ।

শুভকামনা করছি!

সম্পাদনা করুন:

বাছাইয়ে সহায়তা করতে একটি অতিরিক্ত সূচক তৈরি করুন

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

সূচী এবং অর্ডার দ্বারা সরকারী PostgreSQL ডকুমেন্টেশন দেখুন ।

আপনি যদি আপনার ORDER BYপুনর্নির্দেশগুলির সাথে মিলে একটি সূচক তৈরি করেন

CREATE INDEX idx_product_sort ON products (score DESC, title);

তারপরে পোস্টগ্রাগগুলি অনুকূলিত করবে এবং সিদ্ধান্ত নেবে যে সূচকটি ব্যবহার করা বা স্পষ্টত বাছাই করা আরও ব্যয়বহুল। মনে রাখবেন যে কোনও গ্যারান্টি নেই যে পোস্টগ্রিস সূচকটি ব্যবহার করবে ; এটি পারফরম্যান্স অনুকূল করতে এবং সূচক ব্যবহার করে বা স্পষ্টভাবে বাছাইয়ের মধ্যে চয়ন করতে পারে। আপনি যদি এই সূচকটি তৈরি করেন তবে এটির তৈরির ন্যায্যতা প্রমাণ করার জন্য এটি যথেষ্ট পরিমাণে ব্যবহৃত হচ্ছে কিনা তা পর্যবেক্ষণ করুন এবং আপনার বেশিরভাগ ধরণের স্পষ্টভাবে করা হচ্ছে কিনা তা ছেড়ে দিন।

তবুও, এই মুহুর্তে, আপনার 'বাকের পক্ষে সবচেয়ে বড় ব্যাং' সম্ভবত আরও ব্যবহার করা হবে work_mem, তবে এমন কিছু ক্ষেত্রে রয়েছে যে সূচকটি বাছাইয়ের পক্ষে থাকতে পারে।


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

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