একটি ডাটাবেসে স্ট্রিং / রেকর্ডগুলির একটি খুব বড় তালিকার মাধ্যমে কীভাবে দ্রুত অনুসন্ধান করবেন


32

আমার নিম্নলিখিত সমস্যা রয়েছে: আমার কাছে 2 মিলিয়নেরও বেশি রেকর্ডযুক্ত একটি ডাটাবেস রয়েছে have প্রতিটি রেকর্ডের স্ট্রিং ফিল্ড এক্স থাকে এবং আমি রেকর্ডের একটি তালিকা প্রদর্শন করতে চাই যার জন্য ক্ষেত্র এক্সের একটি নির্দিষ্ট স্ট্রিং রয়েছে। প্রতিটি রেকর্ডটি আকারে প্রায় 500 বাইট।

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

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

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

সম্পাদনা

আমি প্রথম পরীক্ষা চালিয়েছি। আমি রেকর্ডগুলি বিভিন্ন পাঠ্য ফাইলগুলিতে বিভক্ত করেছি (প্রতি ফাইল প্রতি 200 টি রেকর্ড) এবং ফাইলগুলি বিভিন্ন ডিরেক্টরিতে রেখেছি (ডিরেক্টরি ট্রি নির্ধারণ করার জন্য আমি একটি ডেটা ফিল্ডের সামগ্রী ব্যবহার করেছি)। আমি প্রায় 40000 ডিরেক্টরিতে প্রায় 50000 ফাইল দিয়ে শেষ করি। আমি তখন ফাইলগুলি সূচী করতে Lucene চালিয়েছি। Lucene ডেমো প্রোগ্রামের সাথে একটি স্ট্রিং অনুসন্ধান করা খুব দ্রুত। বিভক্তকরণ এবং সূচকে কয়েক মিনিট সময় লেগেছে: এটি আমার পক্ষে সম্পূর্ণ গ্রহণযোগ্য কারণ এটি একটি স্থিতিশীল ডেটা সেট যা আমি জিজ্ঞাসা করতে চাই।

পরবর্তী পদক্ষেপটি হ'ল লুসিনকে মূল প্রোগ্রামে সংহত করা এবং লুসিনের ফিরে আসা হিটগুলি প্রাসঙ্গিক রেকর্ডগুলি মূল স্মৃতিতে লোড করতে ব্যবহার করা।


2
2 মিলিয়ন রেকর্ড * 500 বাইট = 1 জিবি ডেটা। এটি অনুসন্ধানের জন্য প্রচুর ডেটা, আপনি যে কোনও পথেই যান - এক্স এর প্রতিটি মান সম্ভবত অনন্য হওয়ার সম্ভাবনা রয়েছে বা এক্স এর সমান মান সহ আপনার অনেক রেকর্ড থাকবে?

1
যে আরো একটি হবে অনেক তথ্য দ্রুত আহরণ জন্য ক্যাশ হিসাবে মেমরিতে স্টোর করার প্রচেষ্টা করা হয়। যা ব্যবহারকারীদের প্রতি সেশনে 1GB এরও বেশি হবে।
ম্যাপেল_শ্যাফ্ট

আমার আগের মন্তব্যটি একটি ওয়েব অ্যাপ্লিকেশন ধরেছে। এটি কি ওয়েব অ্যাপ্লিকেশন?
maple_shaft

এটি একটি ডেস্কটপ অ্যাপ্লিকেশন। রেকর্ডগুলিতে মানগুলি অবশ্যই অনন্য নয়। এছাড়াও, আমি সঠিক ম্যাচের জন্য নয় সাবস্ট্রিং অনুসন্ধান করছি।
জর্জিও

@ ম্যাপেল_শ্যাফ্ট: আমি সম্প্রতি যে রেকর্ডগুলি ব্যবহার করেছি কেবল তা কেবল ক্যাশে করব। যদি আমি ক্যোরির স্ট্রিং পরিবর্তন করি এবং এখনও একটি রেকর্ড মেলে, এটি এখনও ক্যাশে রয়েছে।
জর্জিও

উত্তর:


20

আপনার ডেবিটি ডিবি-র ভিতরে রাখার পরিবর্তে আপনি এগুলিকে আলাদা করে নথির সেট (টেক্সট ফাইল) রাখতে পারেন এবং লিংকটি (পাথ / ইউআরএল ইত্যাদি) ডিবিতে রাখতে পারেন।

এটি অপরিহার্য কারণ, ডিজাইনের দ্বারা এসকিউএল ক্যোয়ারী উপ-স্ট্রিং অনুসন্ধানের পাশাপাশি পুনরুদ্ধার উভয়ই খুব ধীর হবে।

এখন, আপনার সমস্যাটি এমনভাবে তৈরি করা হয়েছে, যাতে স্ট্রিংস সেট রয়েছে এমন পাঠ্য ফাইলগুলি সন্ধান করতে হবে। এখানে দুই সম্ভাবনা আছে।

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

  2. সূচিযুক্ত অনুসন্ধান। এখানে আপনি ধরে নিচ্ছেন যে পাঠ্যে শব্দের সংশ্লেষ রয়েছে এবং অনুসন্ধানটি নির্দিষ্ট শব্দ দৈর্ঘ্যে সীমাবদ্ধ। এই ক্ষেত্রে ডকুমেন্টটি শব্দের সম্ভাব্য সমস্ত ঘটনার উপরে সূচিযুক্ত হয়। একে প্রায়শই "সম্পূর্ণ পাঠ্য অনুসন্ধান" বলা হয়। এটি করার জন্য অ্যালগরিদমের সংখ্যা রয়েছে এবং সরাসরি ব্যবহার করা যেতে পারে এমন ওপেন সোর্স প্রকল্পের সংখ্যা। তাদের মধ্যে অনেকগুলি নীচে ওয়াইল্ড কার্ড অনুসন্ধান, আনুমানিক অনুসন্ধান ইত্যাদি সমর্থন করে:
    ক। অ্যাপাচি লসিন: http://lucene.apache.org/java/docs/index.html
    খ। ওপেনটিফটিএস: http://openfts.sourceforge.net/
    গ। স্পিনক্স http://sphinxsearch.com/

সম্ভবত আপনার যদি প্রশ্নের হিসাবে "স্থির শব্দ" দরকার হয়, তবে দুটি উপায় খুব দ্রুত এবং কার্যকর হবে।


2
এটি একটি আকর্ষণীয় ধারণা তবে এটি সম্ভবত অসম্ভব বলে মনে হয় যে কোনও ডেভেলপার সহজেই 1GB টেক্সটাল ডেটা ডাটাবেস ইঞ্জিনের চেয়ে দ্রুত এবং আরও দক্ষতার সাথে অনুসন্ধান করতে পারেন। আপনার চেয়ে অনেক বেশি চৌকস মানুষ এবং ক্যোয়ারী অপ্টিমাইজারগুলির উপর এটি করার জন্য আমি কঠোর পরিশ্রম করেছি এবং আপনি যে কোনওরকম আরও দক্ষতার সাথে এটি করতে পারবেন তা ভেবে কিছুটা নির্বোধ হবে।
ম্যাপেল_শ্যাফ্ট

4
@ ম্যাপেল_শ্যাফ্ট আমি যে উদাহরণগুলি দিয়েছি তা আরডিবিএমএস ডাটাবেস ইঞ্জিন নয়। আপনি যদি এটি কল করতে চান তবে সেগুলি আরও বেশি "অনুসন্ধান ইঞ্জিনগুলির" মতো। ইনডেক্স (বা হ্যাশ টেবিল) এর বাইরে তালিকা তৈরি করা এবং 1 জিবি ডেটা দিয়ে যখনই প্রতিটি সময় জিজ্ঞাসা করা হয় তখনই আবার অনুসন্ধান করার মধ্যে একটি বিশাল ধারণাগত পার্থক্য রয়েছে। সুতরাং আমি যা পরামর্শ দিচ্ছি তা কোনও গৌণ টুইট নয়।
দীপন মেহতা

এটি একটি আকর্ষণীয় ধারণা বলে মনে হচ্ছে তবে আমি কীভাবে এটি কাজ করব তা অবাক করি। আমার কাছে 2 000 000 এরও বেশি ফাইল থাকবে, প্রতিটি প্রায় অর্ধ কিলোবাইট আকারের। অথবা আপনি কি ফাইল প্রতি একাধিক রেকর্ড থাকার পরামর্শ দিচ্ছেন? একটি ডাটাবেস আর্ট পার্থক্য কি হবে?
জর্জিও

আমি নিশ্চিত নই যে এটি অগত্যা এসকিউএল ফুলটেক্সট সূচকের চেয়ে আরও ভাল কিছু সম্পাদন করবে।
কર્ક ব্রডহર્স্ট

@ জর্জিও - হ্যাঁ পুরো টেক্সট অনুসন্ধান ইঞ্জিনগুলি কীভাবে এটি কাজ করবে। এখানে মূল পার্থক্যটি হ'ল একটি প্রাক সূচকযুক্ত পৃষ্ঠাগুলি বনাম মেমরি অনুসন্ধানে (প্রতিটি বারের জন্য আবার কোনও কোয়েরি আসে)।
দিপান মেহতা

21

আপনি যে প্রযুক্তিটির সন্ধান করছেন তা হ'ল ফুল-পাঠ্য সূচী। বেশিরভাগ আরডিবিএমএসের মধ্যে কিছুটা বিল্ট-ইন ক্ষমতা রয়েছে যা এখানে কাজ করতে পারে বা আপনি ফ্যানসিয়ার পেতে চাইলে এবং / অথবা কেবল এটি স্মৃতিতে চালাতে চান তবে আপনি লুসিনের মতো কিছু ব্যবহার করতে পারেন।


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

8

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


1
হ্যাঁ! আমি একটি গাছের কাঠামোর কথা ভাবছিলাম এবং আমি মনে পড়েছিলাম যে এরকম কিছু ছিল যা আমার উপযোগী হতে পারে তবে আমি ট্রাইয়ের কথা মনে রাখিনি কারণ আমি সেগুলি কখনও ব্যবহার করি নি। স্টোরেজ প্রয়োজনীয়তা সম্পর্কে: মনে রাখবেন যে আমাকে কেবল প্রথম এন এনট্রিগুলি পুনরুদ্ধার করতে হবে (যেমন এন = 100) কারণ এটি 20000 হিট সহ কোনও টেবিলটি তৈরি করার কোনও মানে হয় না। সুতরাং ট্রাইয়ের প্রতিটি নোড সর্বাধিক এন এন্ট্রিগুলিতে নির্দেশ করবে। এছাড়াও, আমি উল্লেখ করতে ভুলে গিয়েছিলাম যে আমার দ্রুত অ্যাক্সেস প্রয়োজন তবে আমার দ্রুত আপডেটের দরকার নেই, কারণ ডেটা কেবল একবার লোড হয়। অনুমোদিত সূচীতে ত্রি ধারণাটি সত্যিই কাজ করতে পারে!
জর্জিও

1
উত্তম উত্তর তবে আপনি যেমন লক্ষ করেছেন, আপনার শব্দের শুরুতে ম্যাচ করার জন্য একটি ট্রাই দুর্দান্ত তবে কোনও সাবস্ট্রিংয়ের সাথে মিলে গেলে দ্রুত জটিল এবং খুব বড় আকারে আসবে ...
কर्क ব্রডহર્স্ট

প্রথম পরীক্ষা হিসাবে, আমি অনুসন্ধান করতে পারা স্ট্রিংগুলিতে উপস্থিত সমস্ত সাব-স্ট্রিংগুলির সেটটি তৈরির চেষ্টা করেছি যা, যদি আমি সঠিকভাবে বুঝতে পারি তবে ট্রাইয়ের পথগুলির সাথে সামঞ্জস্য করি। আমি দৈর্ঘ্যের উপ-স্ট্রিংগুলিতে (JVM এর জন্য 256M হিপ সহ) একটি অপ্রচলিত স্মৃতি ব্যতিক্রম পেয়েছি So সুতরাং আমি ভয় করি যে আমি যদি কোনও ভুল না করে থাকি তবে এই সমাধানটি সম্ভব হয় না।
জর্জিও

5

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

একটি বিকল্প হ'ল এই রেকর্ডগুলির অনন্য শনাক্তকারীদের সংগ্রহ করা যা আপনি অবশ্যই ক্যোয়ারী থেকে পুনরুদ্ধার করতে চান না এবং এগুলিকে সম্ভবত একটি NOT INবা একটিতে অন্তর্ভুক্ত করতে চান NOT EXISTS

সতর্কতার কথা যদিও ব্যবহার করা NOT INবা NOT EXISTSসস্তার না হওয়া প্রবণতা এবং আপনি কোন ডাটাবেস ইঞ্জিনটি ব্যবহার করছেন তার উপর নির্ভর করে আপনার ক্যোয়ারী পারফরম্যান্স বা কোয়েরি প্ল্যানকে নেতিবাচক প্রভাবিত করতে পারে। আক্রান্ত কলামগুলিতে আপনার সমস্ত সূচী ব্যবহার করা হচ্ছে তা নিশ্চিত করতে আপনার চূড়ান্ত ক্যোয়ারিতে একটি ব্যাখ্যা পরিকল্পনা চালান।

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


ম্যাপেল_শ্যাফ্ট এবং @ ওয়াইট বার্নেট: পরামর্শের জন্য অনেক ধন্যবাদ। আমাকে কিছু পড়া এবং বিভিন্ন সমাধান চেষ্টা করতে হবে। সমস্ত ডাটাবেস সম্পূর্ণ সূচক সমর্থন করে না, মাইএসকিউএল (যা আমি বর্তমানে ব্যবহার করছি) করে ( dev.mysql.com/doc/refman/5.5/en/fulltext-search.html )। আমি কিছু পরীক্ষা করার চেষ্টা করব এবং তারপরে এখানে প্রতিবেদন করব।
জর্জিও

2

সেক্ষেত্রে আপনি এটি মিস করেছেন। যদি আপনি ইন-ডিবি সমর্থিত পাঠ্য অনুসন্ধানের পরিবর্তে আপনার ডাটাবেসের জন্য লুসিন ব্যবহার করেন তবে আপনার ডিবিতে পরিবর্তন করার সময় আপনাকে অত্যন্ত সতর্কতা অবলম্বন করতে হবে। আপনি যখন ডিবি এবং বাহ্যিক সংস্থার (লুসিন) উভয় ক্ষেত্রে পরিবর্তন আনতে পারেন তখন আপনি কীভাবে পারমাণবিকতা থাকতে পারবেন তা নিশ্চিত করবেন? হ্যাঁ এটি করা যেতে পারে তবে অনেক কাজ হবে will

সংক্ষেপে, আপনি লসিনকে আপনার ডেটা স্কিমায় রাখলে আপনি ডিবি ট্রানজেকশনাল সমর্থনটি হারাচ্ছেন।


1
উল্লিখিত সমস্যাটি কোনওভাবেই কোনও আরডিএমএসের জন্য উপযুক্ত ফিট বলে মনে হচ্ছে না।
পিটার বি

1

আপনি স্পিংক্স বিবেচনা করেছেন? http://sphinxsearch.com আপনি যদি কোনও তৃতীয় পক্ষের সরঞ্জাম ব্যবহার করতে পারেন তবে এটি আপনি অর্জন করার চেষ্টা করছেন তার জন্য আদর্শ হতে পারে, এটি ব্যক্তিগতভাবে আমি যে কোনও আরডিবিএমএস ব্যবহার করেছি তার চেয়ে সম্পূর্ণ পাঠ্য অনুসন্ধানে এটি আরও দক্ষ efficient


3
এবং ডাউন ভোটের জন্য?
22-28 এ ট্যুইগ করুন

1

এটি কিছুটা আশ্চর্যের বিষয় যে উত্তরের কোনওটিই "ইনভার্টেড ইনডেক্স" শব্দটি উপস্থাপন করে নি , প্রযুক্তিটি অ্যাপাচি লুসিন এবং অন্যান্যদের মতো সমস্ত সমাধানের অন্তর্নিহিত।

উল্টানো সূচকটি শব্দের থেকে দস্তাবেজগুলিতে ম্যাপিং ("রেকর্ড-স্তর বিপরীতমুখী সূচক") বা নথির মধ্যে সুনির্দিষ্ট শব্দের অবস্থান ("শব্দ-স্তর বিপরীত সূচক")।

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

সুতরাং, টিপলসযুক্ত একটি সূচক সম্পর্কে ভাবেন। যখন আপনার উদাহরণ রয়েছে ("উল্টানো", "foo.txt", 123) তবে আপনি কেবল "উল্টো সূচী" পুরো বাক্যাংশটি অনুসন্ধান করার জন্য ("সূচক", "foo.txt", 124) সূচকের অংশ কিনা তা পরীক্ষা করে দেখুন check ।

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

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

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