সম্পাদনা করুন:
ক্ষমাপ্রার্থী হওয়ার সাথে সাথে, আমার এই দাবিটি প্রত্যাহার করতে হবে যে গৃহীত উত্তরটি সর্বদা সঠিক হয় না - এটিতে বর্ণিত হয়েছে যে ভিউটি সর্বদা হিসাবে একইভাবে লিখিত জিনিসটির সাথে সর্বদা অভিন্ন। আমি মনে করি এটি অনস্বীকার্য এবং আমি মনে করি যে আমি এখন জানি আমার ক্ষেত্রে কী চলছে।
আমি এখন মনে করি মূল প্রশ্নের আরও ভাল উত্তর আছে।
মূল প্রশ্নটি হল দৃষ্টিভঙ্গি ব্যবহারের জন্য গাইডিং অনুশীলন হওয়া উচিত কিনা (উদাহরণস্বরূপ, রুটিনগুলিতে এসকিউএল পুনরাবৃত্তি করা যা দু'বার বা তার বেশি বজায় রাখা দরকার)।
আমার উত্তরটি হ'ল "যদি আপনার ক্যোয়ারী উইন্ডো ফাংশন বা এমন কোনও কিছু ব্যবহার করে না যা অপটিমাইজারের দ্বারা ক্যোয়ারিকে সাবকিউরির সাথে আলাদাভাবে আচরণ করার কারণ করে, কারণ সাবকিউরিটি তৈরির খুব কার্য (দৃশ্য হিসাবে উপস্থাপিত হোক না কেন) পারফরম্যান্সকে হ্রাস করতে পারে যদি আপনি রানটাইমে প্যারামিটারগুলি দিয়ে ফিল্টার করছেন।
আমার উইন্ডো ফাংশনের জটিলতা অপ্রয়োজনীয়। এর জন্য ব্যাখ্যা পরিকল্পনা:
SELECT DISTINCT ts.train_service_key,
pc.assembly_key,
count(*) OVER
(PARTITION BY ts.train_service_key) AS train_records
FROM staging.train_service ts
JOIN staging.portion_consist pc
USING (ds_code, train_service_key)
WHERE assembly_key = '185132';
এর চেয়ে অনেক কম ব্যয়বহুল:
SELECT *
FROM (SELECT DISTINCT ts.train_service_key,
pc.assembly_key,
count(*) OVER
(PARTITION BY ts.train_service_key) AS train_records
FROM staging.train_service ts
JOIN staging.portion_consist pc
USING (ds_code, train_service_key)) AS query
WHERE assembly_key = '185132';
আশা করি এটি কিছুটা সুনির্দিষ্ট এবং সহায়ক।
আমার সাম্প্রতিক অভিজ্ঞতায় (আমাকে এই প্রশ্নটি সন্ধানের কারণ হিসাবে), উপরোক্ত গৃহীত উত্তরগুলি সমস্ত পরিস্থিতিতে সঠিক নয়। আমার একটি অপেক্ষাকৃত সাধারণ ক্যোয়ারী রয়েছে যাতে একটি উইন্ডো ফাংশন অন্তর্ভুক্ত:
SELECT DISTINCT ts.train_service_key,
pc.assembly_key,
dense_rank() OVER (PARTITION BY ts.train_service_key
ORDER BY pc.through_idx DESC, pc.first_portion ASC,
((CASE WHEN (NOT ts.primary_direction)
THEN '-1' :: INTEGER
ELSE 1
END) * pc.first_seq)) AS coach_block_idx
FROM (staging.train_service ts
JOIN staging.portion_consist pc USING (ds_code, train_service_key))
যদি আমি এই ফিল্টারটি যুক্ত করি:
where assembly_key = '185132'
আমি যে ব্যাখ্যা পরিকল্পনা পাই তা নীচে:
QUERY PLAN
Unique (cost=11562.66..11568.77 rows=814 width=43)
-> Sort (cost=11562.66..11564.70 rows=814 width=43)
Sort Key: ts.train_service_key, (dense_rank() OVER (?))
-> WindowAgg (cost=11500.92..11523.31 rows=814 width=43)
-> Sort (cost=11500.92..11502.96 rows=814 width=35)
Sort Key: ts.train_service_key, pc.through_idx DESC, pc.first_portion, ((CASE WHEN (NOT ts.primary_direction) THEN '-1'::integer ELSE 1 END * pc.first_seq))
-> Nested Loop (cost=20.39..11461.57 rows=814 width=35)
-> Bitmap Heap Scan on portion_consist pc (cost=19.97..3370.39 rows=973 width=38)
Recheck Cond: (assembly_key = '185132'::text)
-> Bitmap Index Scan on portion_consist_assembly_key_index (cost=0.00..19.72 rows=973 width=0)
Index Cond: (assembly_key = '185132'::text)
-> Index Scan using train_service_pk on train_service ts (cost=0.43..8.30 rows=1 width=21)
Index Cond: ((ds_code = pc.ds_code) AND (train_service_key = pc.train_service_key))
এটি ট্রেন পরিষেবা টেবিলের প্রাথমিক কী সূচক এবং অংশ_সংশ্লিষ্ট তালিকায় একটি অ-অনন্য সূচক ব্যবহার করছে। এটি 90ms এ কার্যকর করে।
আমি একটি ভিউ তৈরি করেছি (একে একে পরিষ্কার করার জন্য এটি এখানে আটকানো হয়েছে তবে এটি একটি দৃশ্যে আক্ষরিকভাবে জিজ্ঞাস্য):
CREATE OR REPLACE VIEW staging.v_unit_coach_block AS
SELECT DISTINCT ts.train_service_key,
pc.assembly_key,
dense_rank() OVER (PARTITION BY ts.train_service_key
ORDER BY pc.through_idx DESC, pc.first_portion ASC, (
(CASE
WHEN (NOT ts.primary_direction)
THEN '-1' :: INTEGER
ELSE 1
END) * pc.first_seq)) AS coach_block_idx
FROM (staging.train_service ts
JOIN staging.portion_consist pc USING (ds_code, train_service_key))
আমি যখন অভিন্ন ফিল্টারটি দিয়ে এই দর্শনটি জিজ্ঞাসা করি:
select * from staging.v_unit_coach_block
where assembly_key = '185132';
এই ব্যাখ্যা পরিকল্পনা:
QUERY PLAN
Subquery Scan on v_unit_coach_block (cost=494217.13..508955.10 rows=3275 width=31)
Filter: (v_unit_coach_block.assembly_key = '185132'::text)
-> Unique (cost=494217.13..500767.34 rows=655021 width=43)
-> Sort (cost=494217.13..495854.68 rows=655021 width=43)
Sort Key: ts.train_service_key, pc.assembly_key, (dense_rank() OVER (?))
-> WindowAgg (cost=392772.16..410785.23 rows=655021 width=43)
-> Sort (cost=392772.16..394409.71 rows=655021 width=35)
Sort Key: ts.train_service_key, pc.through_idx DESC, pc.first_portion, ((CASE WHEN (NOT ts.primary_direction) THEN '-1'::integer ELSE 1 END * pc.first_seq))
-> Hash Join (cost=89947.40..311580.26 rows=655021 width=35)
Hash Cond: ((pc.ds_code = ts.ds_code) AND (pc.train_service_key = ts.train_service_key))
-> Seq Scan on portion_consist pc (cost=0.00..39867.86 rows=782786 width=38)
-> Hash (cost=65935.36..65935.36 rows=1151136 width=21)
-> Seq Scan on train_service ts (cost=0.00..65935.36 rows=1151136 width=21)
এটি উভয় টেবিলগুলিতে পূর্ণ স্ক্যান করছে এবং 17 টি গ্রহণ করে।
আমি এগুলি না আসা পর্যন্ত আমি পোস্টগ্র্রেএসকিউএল (স্বীকৃত উত্তরে প্রকাশিত বহুল আলোচিত মতামত বুঝতে পেরে) দিয়ে উদারভাবে মতামত ব্যবহার করে আসছি। আমার প্রাক-সামগ্রিক ফিল্টারিংয়ের প্রয়োজন হলে আমি বিশেষত ভিউগুলি এড়াতে চাই, যার জন্য আমি সেট-রিটার্নিং ফাংশন ব্যবহার করব।
আমি আরও জানি যে পোস্টগ্রিসএসকিউএল-এর সিটিইগুলি কঠোরভাবে আলাদাভাবে ডিজাইন দ্বারা মূল্যায়ন করা হয়, সুতরাং আমি এসকিউএল সার্ভারের সাথে সেভাবেই ব্যবহার করি না, উদাহরণস্বরূপ, যেখানে তারা সাবকিউরিস হিসাবে অপ্টিমাইজড বলে মনে হয়।
আমার উত্তর, অতএব, এমন উদাহরণ রয়েছে যেখানে মতামতগুলি যে ভিত্তিতে তৈরি হয়েছে সেই প্রশ্নের হিসাবে ঠিকঠাকভাবে সম্পাদন করে না, তাই সাবধানতার পরামর্শ দেওয়া হয়। আমি পোস্টগ্রিজ এসকিউএল 9.6.6 এর উপর ভিত্তি করে আমাজন অরোরা ব্যবহার করছি।
SELECT * FROM my_view WHERE my_column = 'blablabla';
দ্বিতীয়টি আপনার ডেটা মডেলটিকে যে অ্যাপ্লিকেশনটি ব্যবহার করে তাতে স্বচ্ছ করতে ভিউগুলি ব্যবহার করার বিষয়ে। প্রথম উত্সগুলি আপনাকেWHERE my_column = 'blablabla'
দৃশ্যের সংজ্ঞা অনুযায়ী ফিল্টারটি অন্তর্ভুক্ত করতে নির্দেশ করে , ফলস্বরূপ একটি কার্যকর কার্যকর পরিকল্পনার ফলস্বরূপ।