পোস্টগ্রিএসকিউএল লাইক কোয়েরি পারফরম্যান্সের বিভিন্নতা


112

আমি LIKEআমার ডাটাবেসে একটি নির্দিষ্ট টেবিলের প্রশ্নের সম্পর্কিত প্রতিক্রিয়া বারগুলিতে বেশ বড় পরিবর্তন দেখছি । কখনও কখনও আমি 200-400 এমএসের মধ্যে ফলাফল (খুব গ্রহণযোগ্য) পাব তবে অন্য সময় ফলাফলগুলি আসতে 30 সেকেন্ডের বেশি সময় লাগতে পারে।

আমি বুঝতে পারি যে LIKEক্যোয়ারীগুলি খুব সংস্থানীয় সংস্থান তবে আমি কেন বুঝতে পারছি না যে প্রতিক্রিয়ার সময়ে এত বড় পার্থক্য থাকবে। আমি owner1মাঠে একটি বিটি্রি সূচক তৈরি করেছি তবে আমার মনে হয় না এটি LIKEঅনুসন্ধানগুলির সাথে সহায়তা করে । কারো কোন ধারণা আছে?

নমুনা এসকিউএল:

SELECT gid, owner1 FORM parcels
WHERE owner1 ILIKE '%someones name%' LIMIT 10

আমি চেষ্টা করেছি:

SELECT gid, owner1 FROM parcels
WHERE lower(owner1) LIKE lower('%someones name%') LIMIT 10

এবং:

SELECT gid, owner1 FROM parcels
WHERE lower(owner1) LIKE lower('someones name%') LIMIT 10

একই ফলাফল।
সারণি সারি গণনা: প্রায় 95,000।

উত্তর:


280

এফটিএস সমর্থন করে না LIKE

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

জন্য ত্রিগ্রাম সূচী LIKE

অতিরিক্ত মডিউলটি ইনস্টল করুন pg_trgmযা কেবল বাম-অ্যাঙ্কার্ডগুলি নয়, সমস্ত এবং নিদর্শনগুলিকে সমর্থন করার জন্য GIN এবং GiST ট্রাইগ্রাম সূচকগুলির জন্য অপারেটর ক্লাস সরবরাহ করে :LIKEILIKE

উদাহরণ সূচক:

CREATE INDEX tbl_col_gin_trgm_idx  ON tbl USING gin  (col gin_trgm_ops);

বা:

CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);

উদাহরণ ক্যোয়ারী:

SELECT * FROM tbl WHERE col LIKE '%foo%';   -- leading wildcard
SELECT * FROM tbl WHERE col ILIKE '%foo%';  -- works case insensitively as well

Trigrams? সংক্ষিপ্ত স্ট্রিং সম্পর্কে কি?

সূচকযুক্ত মানগুলিতে 3 টিরও কম অক্ষরের শব্দগুলি এখনও কাজ করে। ম্যানুয়াল:

প্রতিটি শব্দের স্ট্রিংয়ে থাকা ট্রিগারগুলির সেট নির্ধারণ করার সময় দুটি স্পেস উপসর্গ এবং একটি স্থান প্রত্যয়যুক্ত বলে মনে করা হয়।

এবং 3 টিরও কম অক্ষরের সাথে নিদর্শনগুলি অনুসন্ধান করবেন? ম্যানুয়াল:

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

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


text_pattern_ops উপসর্গ মিলনের জন্য

কেবল বাম-অ্যাঙ্কার্ড নিদর্শনগুলির জন্য (কোনও শীর্ষস্থানীয় ওয়াইল্ডকার্ড নয়) আপনি বিটি্রি সূচকের জন্য উপযুক্ত অপারেটর শ্রেণির সাথে সর্বোত্তম পাবেন : text_pattern_opsবা varchar_pattern_ops। স্ট্যান্ডার্ড পোস্টগ্রিসের অন্তর্নির্মিত বৈশিষ্ট্য উভয়ই, কোনও অতিরিক্ত মডিউলের প্রয়োজন নেই। অনুরূপ কর্মক্ষমতা, তবে অনেক ছোট সূচক index

উদাহরণ সূচক:

CREATE INDEX tbl_col_text_pattern_ops_idx ON tbl(col text_pattern_ops);

উদাহরণ ক্যোয়ারী:

SELECT * FROM tbl WHERE col LIKE 'foo%';  -- no leading wildcard

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

ডিবিএএসই সম্পর্কিত এই সম্পর্কিত উত্তরের আরও বিশদ, ব্যাখ্যা, উদাহরণ এবং লিঙ্কগুলি:


500K লাইনের একটি টেবিল কোন নেতৃস্থানীয় ওয়াইল্ডকার্ড সঙ্গে, gin_trgm_ops সঙ্গে জিন সূচক 10 বার btree তুলনায় দ্রুততর হচ্ছে মনে হচ্ছে,
নিকোলাস

@নিকোলস: তুলনাটি অনেকগুলি ভেরিয়েবলের উপর নির্ভর করে। মূল দৈর্ঘ্য, ডেটা বিতরণ, প্যাটার্ন দৈর্ঘ্য, সম্ভাব্য সূচি কেবল স্ক্যান ... এবং সর্বাগ্রে গুরুত্বপূর্ণ: পোস্টগ্র্যাস সংস্করণ। পৃষ্ঠা 9.4 এবং 9.5-এ জিআইএন সূচকগুলি যথেষ্ট উন্নত হয়েছে। Pg_trgm এর নতুন সংস্করণ (pg 9.6 সহ প্রকাশ করা হবে) আরও উন্নতি করতে চলেছে।
এরউইন ব্র্যান্ডস্টেটার

1
যদি আমি ডক্সটি সঠিকভাবে পেয়েছি তবে আপনার pg_trgmকমপক্ষে 3 টি অক্ষরের দৈর্ঘ্যের ক্যোরি স্ট্রিংয়ের দরকার আছে, উদাহরণস্বরূপ fo%সূচককে আঘাত করবে না তবে পরিবর্তে একটি স্ক্যান করবে। কিছু খেয়াল করার।
টুউকা মস্তোনেন

1
@ টুকু মস্তোনেন: ভালো কথা। ওয়েল, (বিটম্যাপ) সূচি স্ক্যানগুলি এখনও কাজ করে , তারা কেবল আপনাকে আরও ভাল পারফরম্যান্স কিনতে পারবে না। আমি উপরে কিছু স্পষ্টতা যুক্ত করেছি।
এরউইন ব্র্যান্ডসটেটার

7

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

আপনি যদি ক্ষেত্রের মাঝখানে স্ট্রিং সন্ধান করতে চান তবে আপনার সম্পূর্ণ পাঠ্য বা ট্রাইগ্রাম সূচীগুলিতে সন্ধান করা উচিত । এর মধ্যে প্রথম পোস্টগ্রিস কোরে রয়েছে, অন্যটি অবদানকারী মডিউলগুলিতে উপলব্ধ।


আমি ক্ষেত্রের ছোট হাতের মানতে একটি সূচক তৈরি করার কথা চিন্তা করিনি। এইভাবে আমি ক্যোয়ারী পাঠ্যটি জিজ্ঞাসা করার আগে ব্যাকএন্ডে লোয়ারকেসে রূপান্তর করতে পারি।
জেসন

4

পোস্টগ্রেএসকিউএল-এ আপনি ভিন্ন ধরণের সূচকটি ওয়াইল্ডস্পিড ইনস্টল করতে পারেন । ওয়াইল্ডস্পিড% শব্দ% ওয়াইল্ডকার্ড নিয়ে কাজ করে, কোনও সমস্যা নেই। নেতিবাচক দিকটি সূচকের আকার, এটি বড়, খুব বড় হতে পারে।


3

পোস্টগ্রিস্কল-এ লাইক ক্যোয়ারী পারফরম্যান্সের উন্নতির জন্য দয়া করে নীচের বর্ণিত ক্যোয়ারীটি সম্পাদন করুন। বড় টেবিলগুলির জন্য এই জাতীয় সূচক তৈরি করুন:

CREATE INDEX <indexname> ON <tablename> USING btree (<fieldname> text_pattern_ops)

এটি কেবল তখনই কাজ করে যদি প্যাটার্নটি কোনও ওয়াইল্ডকার্ড দিয়ে শুরু না হয় - এই ক্ষেত্রে প্রথম দুটি নমুনা প্রশ্ন দুটিই একটি ওয়াইল্ডকার্ড দিয়ে শুরু করে।
সিবিজেড

1

এটি মূল্যবান কিসের জন্য, জ্যাঙ্গো ওআরএম এটিকে সংবেদনহীন করার UPPER(text)জন্য সমস্ত LIKEপ্রশ্নের জন্য ব্যবহার করতে ঝোঁক,

UPPER(column::text)অন্য কোনও জিনিসের বিপরীতে আমার সূচক যুক্ত করা আমার সিস্টেমে ব্যাপকভাবে গতি বাড়িয়েছে।

যতদূর এগিয়ে%, হ্যাঁ এটি একটি সূচক ব্যবহার করবে না। একটি দুর্দান্ত ব্যাখ্যা জন্য এই ব্লগ দেখুন:

https://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning


1

আমার সম্প্রতি 200000 রেকর্ড রয়েছে এমন একটি টেবিলের সাথে আমার একই ধরণের সমস্যা হয়েছিল এবং আমার পুনরাবৃত্ত লাইক কোয়েরি করা দরকার। আমার ক্ষেত্রে, অনুসন্ধানের স্ট্রিংটি স্থির ছিল। অন্যান্য ক্ষেত্র বৈচিত্র্যময়। কারণ, আমি আবার লিখতে সক্ষম হয়েছি:

SELECT owner1 FROM parcels
WHERE lower(owner1) LIKE lower('%someones name%');

যেমন

CREATE INDEX ix_parcels ON parcels(position(lower('someones name') in lower(owner1)));

SELECT owner1 FROM parcels
WHERE position(lower('someones name') in lower(owner1)) > 0;

প্রশ্নগুলি দ্রুত ফিরে এসে যখন যাচাই করে সূচকটি ব্যবহার করে সূচকটি ব্যবহার করা হচ্ছে তখন আমি আনন্দিত হয়েছিল EXPLAIN ANALYZE:

 Bitmap Heap Scan on parcels  (cost=7.66..25.59 rows=453 width=32) (actual time=0.006..0.006 rows=0 loops=1)
   Recheck Cond: ("position"(lower(owner1), 'someones name'::text) > 0)
   ->  Bitmap Index Scan on ix_parcels  (cost=0.00..7.55 rows=453 width=0) (actual time=0.004..0.004 rows=0 loops=1)
         Index Cond: ("position"(lower(owner1), 'someones name'::text) > 0)
 Planning time: 0.075 ms
 Execution time: 0.025 ms

0

আপনার পছন্দ মত প্রশ্নগুলি সম্ভবত আপনি তৈরি সূচকগুলি ব্যবহার করতে পারবেন না কারণ:

1) আপনার লাইক মানদণ্ডটি একটি ওয়াইল্ডকার্ড দিয়ে শুরু হয়।

2) আপনি আপনার পছন্দ মতো মানদণ্ড সহ একটি ফাংশন ব্যবহার করেছেন।


0

যখনই আপনি কোনও কলামে ফাংশনগুলি যেমন যেমন LIKE, ILIKE, Upper, নিম্ন ইত্যাদি ব্যবহার করে কোনও ধারা ব্যবহার করেন তখন পোস্টগ্রাগেস আপনার স্বাভাবিক সূচকটিকে বিবেচনায় নেবে না। এটি প্রতিটি সারি পেরিয়ে টেবিলের একটি সম্পূর্ণ স্ক্যান করবে এবং তাই এটি ধীর হবে।

সঠিক উপায়টি হ'ল আপনার ক্যোয়ারী অনুসারে একটি নতুন সূচি তৈরি করা হবে। উদাহরণস্বরূপ যদি আমি কেস সংবেদনশীলতা ছাড়াই কোনও কলামটি মেলতে চাই এবং আমার কলামটি একটি বর্ণনাকার। তাহলে আপনি এটি এটি করতে পারেন।

create index ix_tblname_col_upper on tblname (UPPER(col) varchar_pattern_ops);

একইভাবে যদি আপনার কলামটি একটি পাঠ্য হয় তবে আপনি এটির মতো কিছু করুন

create index ix_tblname_col_upper on tblname (UPPER(col) text_pattern_ops);

একইভাবে আপনি উপরের ফাংশনটি অন্য যে কোনও ফাংশনে চান তা পরিবর্তন করতে পারেন।

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