সিটিই কেন ইনলাইন সাবকোয়্যারির চেয়ে অনেক খারাপ


11

আমি কীভাবে ক্যোরির পরিকল্পনাকারী পোস্টগ্রেসক্লিতে কাজ করে তা আরও ভাল করে বোঝার চেষ্টা করছি।

আমার এই প্রশ্নটি রয়েছে:

select id from users 
    where id <> 2
    and gender = (select gender from users where id = 2)
    order by latest_location::geometry <-> (select latest_location from users where id = 2) ASC
    limit 50

এটি ব্যবহারকারীদের টেবিলে প্রায় 500k এন্ট্রি সহ আমার ডেটাবেজে 10 মিমেরও কম সময়ে চলে।

তারপরে আমি ভেবেছিলাম যে সদৃশ সাবলেটগুলি এড়াতে আমি কোয়েরিটি সিটিই হিসাবে আবার লিখতে পারি, এটির মতো:

with me as (
    select * from users where id = 2
)
select u.id, u.popularity from users u, me 
    where u.gender = me.gender
    order by  u.latest_location::geometry <-> me.latest_location::geometry ASC
    limit 50;

তবে এই পুনর্লিখিত ক্যোয়ারী প্রায় 1 সেকেন্ডে চলে! কেন এমন হয়? আমি ব্যাখ্যাগুলিতে দেখছি যে এটি জ্যামিতি সূচকটি ব্যবহার করে না, তবে এর জন্য কিছু করা যায়? ধন্যবাদ!

ক্যোয়ারী লেখার আরেকটি উপায় হ'ল:

select u.id, u.popularity from users u, (select gender, latest_location from users where id = 2) as me 
    where u.gender = me.gender
    order by  u.latest_location::geometry <-> me.latest_location::geometry ASC
    limit 50;

তবে এটিও সিটিইর মতো ধীর হবে।

অন্যদিকে যদি আমি আমার পরামিতিগুলি বের করি এবং স্থিরভাবে সেগুলি সন্নিবেশ করি তবে কোয়েরিটি আবার দ্রুত is

select u.id, u.popularity from users u
    where u.gender = 'male'
    order by  u.latest_location::geometry <-> '0101000000A49DE61DA71C5A403D0AD7A370F54340'::geometry ASC
    limit 50;

প্রথম (দ্রুত) ক্যোয়ারীর ব্যাখ্যা দিন

 Limit  (cost=5.69..20.11 rows=50 width=36) (actual time=0.512..8.114 rows=50 loops=1)
   InitPlan 1 (returns $0)
     ->  Index Scan using users_pkey on users users_1  (cost=0.42..2.64 rows=1 width=32) (actual time=0.032..0.033 rows=1 loops=1)
           Index Cond: (id = 2)
   InitPlan 2 (returns $1)
     ->  Index Scan using users_pkey on users users_2  (cost=0.42..2.64 rows=1 width=4) (actual time=0.009..0.010 rows=1 loops=1)
           Index Cond: (id = 2)
   ->  Index Scan using users_latest_location_gix on users  (cost=0.41..70796.51 rows=245470 width=36) (actual time=0.509..8.100 rows=50 loops=1)
         Order By: (latest_location <-> $0)
         Filter: (gender = $1)
         Rows Removed by Filter: 20
 Total runtime: 8.211 ms
(12 rows)

দ্বিতীয় (ধীর) ক্যোয়ারীর ব্যাখ্যা দাও

Limit  (cost=62419.82..62419.95 rows=50 width=76) (actual time=1024.963..1024.970 rows=50 loops=1)
   CTE me
     ->  Index Scan using users_pkey on users  (cost=0.42..2.64 rows=1 width=221) (actual time=0.037..0.038 rows=1 loops=1)
           Index Cond: (id = 2)
   ->  Sort  (cost=62417.18..63030.86 rows=245470 width=76) (actual time=1024.959..1024.963 rows=50 loops=1)
         Sort Key: ((u.latest_location <-> me.latest_location))
         Sort Method: top-N heapsort  Memory: 28kB
         ->  Hash Join  (cost=0.03..54262.85 rows=245470 width=76) (actual time=0.122..938.131 rows=288646 loops=1)
               Hash Cond: (u.gender = me.gender)
               ->  Seq Scan on users u  (cost=0.00..49353.41 rows=490941 width=48) (actual time=0.021..465.025 rows=490994 loops=1)
               ->  Hash  (cost=0.02..0.02 rows=1 width=36) (actual time=0.054..0.054 rows=1 loops=1)
                     Buckets: 1024  Batches: 1  Memory Usage: 1kB
                     ->  CTE Scan on me  (cost=0.00..0.02 rows=1 width=36) (actual time=0.047..0.049 rows=1 loops=1)
 Total runtime: 1025.096 ms

3
আমি সম্প্রতি এ সম্পর্কে লিখেছি; দেখতে blog.2ndquadrant.com/postgresql-ctes-are-optimization-fences । যদিও বর্তমানে কিছু ডিএনএস সমস্যা রয়েছে যা সেই সাইটের পুনরায় ব্যবহারযোগ্যতা সীমাবদ্ধ করতে পারে। FROMসেরা ফলাফলের জন্য সিটিই পদটির পরিবর্তে একটি সাবকিউরি চেষ্টা করুন ।
ক্রেগ রিঞ্জার

আপনি যদি (select id, latest_location from users where id = 2)সিটি হিসাবে ব্যবহার করেন? হয়তো এটা * যে এই সমস্যা হয় যার ফলে হয়
চা

আমি ভাবতাম যে আপনি বিপরীত লিঙ্গের নিকটতম ব্যবহারকারীদের সন্ধান করবেন :)

@ চাচা কেবল সিটিতে লিঙ্গ এবং অবস্থান নির্বাচন করতে গতিতে কোনও পার্থক্য তৈরি করে না। (আমার ক্ষেত্রে আমি অনুরূপ ব্যবহারকারীর গড় গড় নিতে চাই, কেবলমাত্র আমি প্রশ্নের
উত্তরটি

@ ক্রেইগ্রিঞ্জার আমি এটির অপ্টিমাইজেশনের বেড়াটি ভাবি না। আমি আপনার পরামর্শটি চেষ্টা করেছিলাম এবং এটিও ধীর ছিল। অন্যদিকে, আমি যদি ম্যানুয়ালি প্যারামিটারগুলি বের করি তবে এটি দ্রুত (এবং এটি আমার ক্ষেত্রে একটি আসল বিকল্প, শেষ ফলাফল যাইহোক একটি ফাংশন)।
vilo

উত্তর:


11

এটা চেষ্টা কর:

with me as (
    select * from users where id = 2
)
select u.id, u.popularity from users u, me 
    where u.gender = (select gender from me)
    order by  u.latest_location::geometry <-> (select latest_location from me)::geometry ASC
    limit 50;

আমি যখন দ্রুত পরিকল্পনার দিকে তাকাই তখন আমার দিকে কী ঝাঁপিয়ে পড়ে (সাহসী):

 সীমা (ব্যয় = 5.69..20.11 সারি = 50 প্রস্থ = 36) (আসল সময় = 0.512..8.114 সারি = 50 লুপ = 1)
   ইন্সপ্ল্যান 1 ( প্রত্যাবর্তন $ 0 )
     -> ব্যবহারকারীদের ব্যবহারকারীদের_পিকে ব্যবহার করে সূচক স্ক্যান করুন_1 (ব্যয় = 0.42..2.64 সারি = 1 প্রস্থ = 32) (প্রকৃত সময় = 0.032..0.033 সারি = 1 লুপ = 1)
           সূচকের অবস্থা: (আইডি = 2)
   ইন্সপ্লেয়ান 2 ( returns 1 প্রদান করে )
     -> ব্যবহারকারীদের ব্যবহারকারীদের_পিকে ব্যবহার করে সূচক স্ক্যান করুন 3 (ব্যয় = 0.42..2.64 সারি = 1 প্রস্থ = 4) (প্রকৃত সময় = 0.009..0.010 সারি = 1 লুপ = 1)
           সূচকের অবস্থা: (আইডি = 2)
   -> ব্যবহারকারীদের উপর_লিস্ট_লোকেশন_গিক্স ব্যবহার করে সূচক স্ক্যান (ব্যয় = 0.41..70796.51 সারি = 245470 প্রস্থ = 36) (প্রকৃত সময় = 0.509..8.100 সারি = 50 লুপ = 1)
         অর্ডার করুন: (সর্বশেষ_লোকেশন   $ 0 )
         ফিল্টার: (লিঙ্গ = $ 1 )
         সারিগুলি ফিল্টার দ্বারা সরানো হয়েছে: 20
 মোট রানটাইম: 8.211 এমএস
(12 সারি)

ধীর সংস্করণে, ক্যোয়ারী পরিকল্পক উপর সমতা অপারেটর নির্ণয় করা হয় genderএবং জ্যামিতি অপারেটর latest_locationএকটি প্রেক্ষাপটে যোগদানের , যেখানে থেকে মান meপ্রতিটি সারির (যদিও এটি সঠিকভাবে শুধুমাত্র 1 টি সারি আনুমানিক করেছে) সঙ্গে পরিবর্তিত হতে পারে। দ্রুত সংস্করণে মানগুলি genderএবং স্কেলারlatest_location হিসাবে বিবেচিত হয় কারণ এগুলি ইনলাইন সাবকিউরিগুলি দ্বারা নির্গত হয়, যা ক্যোয়ারার পরিকল্পনাকারীকে বলে যে এটির মোকাবেলায় প্রতিটিটির একটির মান রয়েছে। আপনি যখন আক্ষরিক মানগুলি পেস্ট করেন তখন একই কারণেই আপনি দ্রুত পরিকল্পনা পান।


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