পোস্টগ্রিসে বাছাইয়ের গতি বাড়ানোর জন্য সূচকটি কীভাবে ব্যবহার করবেন


10

আমি পোস্টগ্রিজ 9.4 ব্যবহার করছি।

messagesনিম্নলিখিত রূপরেখা রয়েছে: বার্তা feed_id জন্যে, এবং posted_at হয়েছে, এছাড়াও বার্তা একটি পিতা বা মাতা বার্তা (জবাব দেওয়া ক্ষেত্রে) থাকতে পারে।

                    Table "public.messages"
            Column            |            Type             | Modifiers
------------------------------+-----------------------------+-----------
 message_id                   | character varying(255)      | not null
 feed_id                      | integer                     |
 parent_id                    | character varying(255)      |
 posted_at                    | timestamp without time zone |
 share_count                  | integer                     |
Indexes:
    "messages_pkey" PRIMARY KEY, btree (message_id)
    "index_messages_on_feed_id_posted_at" btree (feed_id, posted_at DESC NULLS LAST)

আমি নির্দেশিত সমস্ত বার্তা ফিরে দিতে চাই share_count, তবে প্রত্যেকটির জন্য parent_idআমি কেবল একটি বার্তা দিতে চাই। অর্থাত্ যদি একাধিক বার্তাগুলির একই থাকে parent_idতবে কেবলমাত্র সর্বশেষতম একটি ( posted_at) প্রত্যাবর্তন হবে। এই parent_idনাল হতে পারে, নাল সহ বার্তাগুলি parent_idসমস্ত ফিরে আসা উচিত।

আমার ব্যবহৃত ক্যোয়ারীটি হ'ল:

WITH filtered_messages AS (SELECT * 
                           FROM messages
                           WHERE feed_id IN (7) 
                           AND (posted_at >= '2015-01-01 04:00:00.000000') 
                           AND (posted_at < '2015-04-28 04:00:00.000000'))
    SELECT *
    FROM (SELECT DISTINCT ON(COALESCE(parent_id, message_id)) parent_id,
                          message_id, 
                          posted_at, 
                          share_count
          FROM filtered_messages
          ORDER BY COALESCE(parent_id, message_id), posted_at DESC NULLS LAST
         ) messages
    ORDER BY share_count DESC NULLS LAST, posted_at DESC NULLS LAST;

এসকিউএল ফিডল- এ http://sqlfiddle.com/#!15/588e5/1/0 , এখানে আমি স্কিমা, সঠিক জিজ্ঞাসা এবং প্রত্যাশিত ফলাফলটি সংজ্ঞায়িত করেছি।

বার্তাগুলির টেবিলটি বড় হয়ে গেলে ক্যোয়ারীর কার্য সম্পাদন ধীর হয়। আমি একাধিক বাছাই সূচক যুক্ত করার চেষ্টা করেছি, তবে এটি সূচকটি ব্যবহার করে বলে মনে হচ্ছে না। এখানে ব্যাখ্যাটি দেওয়া হয়েছে: http://explain.depesz.com/s/Sv2

আমি কীভাবে সঠিক সূচক তৈরি করতে পারি?


প্রথম নজরে, ORDER BYসাবকোয়ারিটি সম্পূর্ণ অকেজো less তদ্ব্যতীত, লিঙ্কযুক্ত পরিকল্পনা পোস্ট করা ক্যোয়ারির ফলাফল হতে পারে না - metadataউদাহরণস্বরূপ কোনও উল্লেখ নেই ।
dezso

আপনার বর্ণনা ভূমিকা কাভার করে না feed_idএবং posted_atএবং আপনি উল্লেখ না metadataএ সব, যা একটি JSON- টাইপ মনে হচ্ছে? আপনার প্রশ্নটি ধারাবাহিক করতে দয়া করে মেরামত করুন। আপনি সিটিইতে> 500k সারি নির্বাচন করুন ... সারণীতে কত সারি রয়েছে? আপনি সাধারণত সিটিইতে কত শতাংশ সারি নির্বাচন করেন? সারি কত শতাংশ আছে parent_id IS NULL? পারফরম্যান্স প্রশ্নগুলির জন্য [পোস্টগ্রেকএইচএল-পারফরম্যান্স] ট্যাগের তথ্যটি বিবেচনা করুন ।
এরউইন ব্র্যান্ডসটেটার

এছাড়াও গুরুত্বপূর্ণ: প্রতিটি জন্য কত সারি parent_id? (মিনিট / গড় / সর্বোচ্চ)
এরউইন ব্র্যান্ডসটেটার

দুঃখিত, আমি কয়েকটি কলাম কমানোর মাধ্যমে প্রশ্নটি আরও স্পষ্ট করার চেষ্টা করছিলাম, শেয়ার_কাউন্টটি আসলে হস্টোরে ছিল metadata। বর্তমানে বার্তাগুলির সারণীতে 10 মিলির ডেটা রয়েছে তবে দ্রুত বাড়ছে। আমি প্রতিটি ফিড_আইডির জন্য পার্টিশন সারণিতে পৃথক করার কথা ভাবছি। যেহেতু আমি কেবল প্রতি ফিড আইডি আনছি। নাল না হয়ে প্যারেন্ট_আইডি নলের শতাংশ প্রায় 60% / 40%। একটি সাধারণ আনার টেবিলের প্রায় 1-2% থাকে। (প্রায় 100 কে বার্তাগুলি) 100K এর জন্য পারফরম্যান্স প্রায় 1s এর কাছাকাছি, তবে একবার 500K + এ এটি বিটম্যাপ সূচক ব্যবহার করে এবং সাধারণত 10s লাগে।
ঝাওহান ওয়েং

উত্তর:


9

প্রশ্ন

এই ক্যোয়ারী যে কোনও ক্ষেত্রে যথেষ্ট দ্রুত হওয়া উচিত:

SELECT parent_id, message_id, posted_at, share_count
FROM   messages
WHERE  feed_id = 7
AND    posted_at >= '2015-01-01 4:0:0'
AND    posted_at <  '2015-04-28 4:0:0'
AND    parent_id IS NULL  -- match index condition
UNION ALL
(
SELECT DISTINCT ON(parent_id)
       parent_id, message_id, posted_at, share_count
FROM   messages
WHERE  feed_id = 7
AND    posted_at >= '2015-01-01 4:0:0'
AND    posted_at <  '2015-04-28 4:0:0'
AND    parent_id IS NOT NULL  -- match index condition
ORDER  BY parent_id, posted_at DESC NULLS LAST
)
ORDER  BY share_count DESC NULLS LAST, posted_at DESC NULLS LAST;
  • সিটিই এখানে এমন কিছু করে না যা একটি সরল subquery সরবরাহ করতে পারে না। এবং একটি সিটিই একটি অপ্টিমাইজেশন বাধা প্রবর্তন করে যেহেতু এটি পৃথকভাবে কার্যকর করা হয় এবং এর ফলাফলটি বাস্তবায়িত হয়।

  • আপনার প্রয়োজনের তুলনায় আপনার আরও একটি সাব-কোয়েরি স্তর রয়েছে।

  • অভিব্যক্তি (COALESCE(parent_id, message_id)একটি সরল সূচকের সাথে সামঞ্জস্যপূর্ণ নয়, আপনাকে সেই অভিব্যক্তিতে একটি সূচি প্রয়োজন। তবে এটি ডেটা বিতরণের উপর নির্ভর করে খুব কার্যকর নাও হতে পারে। বিস্তারিত তথ্যের জন্য নীচে আমার লিঙ্কগুলি অনুসরণ করুন।

  • সাধারণ কেসকে parent_id IS NULLআলাদা আলাদা করে বিচ্ছিন্ন করা SELECTসর্বোত্তম প্রদান করতে পারে বা নাও পারে। বিশেষত না, যদি যাইহোক এটি বিরল ঘটনা, সেই ক্ষেত্রে একটি সূচকের সাথে একটি সম্মিলিত ক্যোয়ারী আরও (COALESCE(parent_id, message_id)ভাল সম্পাদন করতে পারে। অন্যান্য বিবেচনা প্রযোজ্য ...

সূচক

বিশেষত যখন এই সূচকগুলি সমর্থন করে:

CREATE INDEX messages_idx_null ON messages (
  feed_id
, posted_at DESC NULLS LAST
, share_count DESC NULLS LAST
, parent_id, message_id
)
WHERE parent_id IS NULL;

CREATE INDEX messages_idx_notnull ON messages (
  feed_id
, posted_at DESC NULLS LAST
, share_count DESC NULLS LAST
, parent_id, message_id
)
WHERE parent_id IS NOT NULL;

দুটি আংশিক সূচকগুলি পুরো টেবিলকে একসাথে coverেকে দেয় এবং একক মোট সূচক হিসাবে প্রায় একই আকারের হয়।

parent_id, message_idআপনি যদি কেবলমাত্র সূচি-স্ক্যানগুলি থেকে বের হয়ে যান তবে সর্বশেষ দুটি কলামগুলি কেবল তা বোঝায় । অন্যথায় এগুলি উভয় সূচক থেকে সরান।

এসকিউএল ফিডল।

নিখোঁজ বিশদের উপর নির্ভর করে, DISTINCT ONউদ্দেশ্যটির জন্য সেরা কোয়েরি কৌশল হতে পারে বা নাও হতে পারে। এখানে বিস্তারিত ব্যাখ্যা রিড করুন:

এবং সম্ভবত এখানে দ্রুত বিকল্পগুলি:

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