মাইএসকিউএলে একটি ভিআরএআরআর ক্ষেত্রে সম্ভাব্য আইএনডেক্স EX


40

আমি একটি মাইএসকিউএল ডাটাবেসে কাজ করছি , এই জাতীয় টেবিল সহ:

+--------------+
|  table_name  |
+--------------+
|    myField   |
+--------------+

... এবং আমাকে এরকম অনেকগুলি প্রশ্ন করা দরকার (তালিকার 5-10 স্ট্রিং সহ) :

SELECT myField FROM table_name
WHERE myField IN ('something', 'other stuff', 'some other a bit longer'...)

প্রায় 24.000.000 অনন্য সারি থাকবে

1) আমার জন্য আমার একটি FULLTEXTবা INDEXকী ব্যবহার করা উচিত VARCHAR(150)?
2) আমি চরগুলি 150 থেকে 220 বা 250 তে বাড়িয়ে দিলে ... এটি কি খুব বড় পার্থক্য করবে? (এটি গণনা করার কোনও উপায় আছে কি?)
3) যেমনটি আমি বলেছি, তারা অনন্য হতে চলেছে, তাই মাইফিল্ডটি একটি প্রাথমিক কী হতে হবে । একটি ক্ষেত্রের মধ্যে প্রাইমারী কী যুক্ত করা কি বিরল নয় যা ইতিমধ্যে একটি ভেরচার ইন্ডেক্স / ফুলটেক্সট?


স্বতন্ত্রতার জন্য আপনাকে প্রাথমিক ব্যবহার করার দরকার নেই। এর জন্য ইতিমধ্যে অনন্য আছে।
kommradHomer

উত্তর:


62

পরামর্শ # 1: স্ট্যান্ডার্ড ইনডেক্সিং

CREATE TABLE mytable
(
    id int not null auto_increment,
    myfield varchar(255) not null,
    primary key (id),
    key (myfield)
);

আপনি যদি এটির মতো সূচক করেন তবে আপনি পুরো স্ট্রিংটি সন্ধান করতে পারেন বা বামমুখী পছন্দ মতো অনুসন্ধান করতে পারেন

পরামর্শ # 2: ফুলটেক্স ইনডেক্সিং

CREATE TABLE mytable
(
    id int not null auto_increment,
    myfield varchar(255) not null,
    primary key (id),
    fulltext (myfield)
);

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

ফুলটেক্স ইনডেক্সে গত দুই বছর থেকে আমার অন্যান্য পোস্টগুলি এখানে

পরামর্শ # 3: হ্যাশ সূচক ing

CREATE TABLE mytable
(
    id int not null auto_increment,
    myfield varchar(255) not null,
    hashmyfield char(32) not null,
    primary key (id),
    key (hashmyfield)
);

যদি আপনি একটি নির্দিষ্ট মান খুঁজছেন এবং সেই মানগুলি 32 টি অক্ষরেরও বেশি দৈর্ঘ্য হতে পারে তবে আপনি হ্যাশ মানটি সংরক্ষণ করতে পারেন:

INSERT INTO mytable (myfield,hashmyfield)
VALUES ('whatever',MD5('whatever'));

এইভাবে, আপনি ফলাফলগুলি পুনরুদ্ধার করতে কেবল হ্যাশ মানগুলি অনুসন্ধান করুন

SELECT * FROM mytable WHERE hashmyfield = MD5('whatever');

একবার চেষ্টা করে দেখো !!!


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

2
এখানে হ্যাশ বিকল্পটি এখনও একটি পাঠ্য এবং 32 বাইট যা সত্যই 16 বাইট। আপনি বিউটি (বাম (এমডি 5 ('যাই হোক না কেন'), 16), 16), 16, -10) সহ একটি বিগিন্ট ফিল্ড ব্যবহার করতে পারেন। এখানে কোনও 16 বাইটের সংখ্যা নেই তবে আপনি
এমড

1
সূচিযুক্ত হবে এমন স্ট্রিং উত্পাদন করতে MD5 বা SHA1 ব্যবহার করা ভাল নয়। এমডি 5 বা এসএএএ 1 এর মতো হ্যাশিং ফাংশনগুলির দ্বারা উত্পাদিত স্ট্রিংগুলির বিতরণ একটি বৃহত স্থানে এলোমেলোভাবে হয় যা আপনার সূচকের দক্ষতা হ্রাস করে, যা INSERT এবং নির্বাচন নির্বাচন বিবরণিকে ধীর করতে পারে। এখানে এটির ব্যাখ্যা দিয়ে পোস্ট করা হচ্ছে: কোড -পিসেন্টার.com/…
মিঃ এম

আমি ক্ষমা চেয়ে নিচ্ছি কারণ এটি একটি পুরানো থ্রেড, তবে আমার প্রশ্নটি এর সাথে সরাসরি সম্পর্কিত তবে উপরের এবং অন্যান্য অনুরূপ নিবন্ধগুলি পড়ার থেকে আমি আমার প্রয়োজনের একটি পরিষ্কার উত্তর পেতে সক্ষম হই না। আমার পরিস্থিতিটি হ'ল: আমি একটি খুব প্রাথমিক স্টক সিস্টেম বিকাশ করছি যা আপাতত কেবল একটি টেবিল নিয়ে গঠিত। এটি কোনও এপিআইয়ের মাধ্যমে বাহ্যিকভাবে অ্যাক্সেস করা যায় যাতে সমস্ত কনফিগারেশন অন্যত্র অনুষ্ঠিত হয় - এই কারণেই আমাদের কেবল একটি একক টেবিলের প্রয়োজন। আমি যে দুটি কলামকে ইনডেক্সিংয়ের বিষয়ে ভাবছি, তার দৈর্ঘ্য <20 টি বর্ণের প্রায় 200 টি অনন্য এন্ট্রি থাকবে। আমাকে সূচি যোগ করার কথা বিবেচনা করা উচিত?
মাইক

এটি কি অনুসন্ধানের মতো বামমুখী like 'a%'?
হিসাবরক্ষক

18

মাইএসকিউএল আপনাকে প্রিফিক্সড ইনডেক্স সংজ্ঞায়িত করতে সক্ষম করে যার অর্থ আপনি সূচিত করতে মূল স্ট্রিং থেকে প্রথম এন অক্ষরকে সংজ্ঞায়িত করেছেন, এবং কৌশলটি এমন একটি এন নির্বাচন করতে হবে যা ভাল নির্বাচন করতে যথেষ্ট দীর্ঘ, তবে স্থান বাঁচাতে যথেষ্ট সংক্ষিপ্ত। আপনি পুরো কলামটি সূচিযুক্ত করে তুলতে সূচকটিকে প্রায় দরকারী হিসাবে উপস্থাপিত করতে যথেষ্ট দীর্ঘ হওয়া উচিত।

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

+-----+-----------+
| id  | value     |
+-----+-----------+
| 1   | abc       |
| 2   | abd       |
| 3   | adg       |
+-----+-----------+

আমরা যদি কেবলমাত্র প্রথম অক্ষরকে সূচী করি (এন = 1), তবে সূচীকরণ সারণী নিম্নলিখিত টেবিলের মতো দেখাবে:

+---------------+-----------+
| indexedValue  | rows      |
+---------------+-----------+
| a             | 1,2,3     |
+---------------+-----------+

এই ক্ষেত্রে, সূচী নির্বাচনটি IS = 1/3 = 0.33 এর সমান।

আসুন এখন দেখা যাক আমরা যদি সূচী অক্ষরের সংখ্যা দুটি (এন = 2) বৃদ্ধি করি তবে কী হবে।

+---------------+-----------+
| indexedValue  | rows      |
+---------------+-----------+
| ab             | 1,2      |
| ad             | 3        |
+---------------+-----------+

এই দৃশ্যে আইএস = 2/3 = 0.66 যার অর্থ আমরা সূচকের নির্বাচনকে বাড়িয়েছি, তবে আমরা সূচকের আকারও বাড়িয়েছি। কৌশলটি হ'ল ন্যূনতম সংখ্যা এনটি সন্ধান করা যা সর্বাধিক সূচক নির্বাচনতে ফলাফল করবে ।

আপনার ডাটাবেস টেবিলের জন্য গণনা করতে পারেন এমন দুটি পদ্ধতি রয়েছে। আমি এই ডাটাবেস ডাম্প উপর বিক্ষোভ করব ।

ধরা যাক আমরা সূচীতে টেবিল কর্মীদের কলাম শেষের নামটি যুক্ত করতে চাই এবং আমরা সবচেয়ে কম সংখ্যক এন সংজ্ঞায়িত করতে চাই যা সেরা সূচক নির্বাচন করতে পারে।

প্রথমে সর্বাধিক ঘন ঘন শেষ নামগুলি শনাক্ত করা যাক:

select count(*) as cnt, last_name from employees group by employees.last_name order by cnt

+-----+-------------+
| cnt | last_name   |
+-----+-------------+
| 226 | Baba        |
| 223 | Coorg       |
| 223 | Gelosh      |
| 222 | Farris      |
| 222 | Sudbeck     |
| 221 | Adachi      |
| 220 | Osgood      |
| 218 | Neiman      |
| 218 | Mandell     |
| 218 | Masada      |
| 217 | Boudaillier |
| 217 | Wendorf     |
| 216 | Pettis      |
| 216 | Solares     |
| 216 | Mahnke      |
+-----+-------------+
15 rows in set (0.64 sec)

আপনি দেখতে পাচ্ছেন, শেষ নাম বাবাকে সবচেয়ে বেশি ঘন ঘন বলা হয়। এখন আমরা সবচেয়ে বেশিবার যে এটি করতে যাচ্ছি LAST_NAME উপসর্গ, পাঁচটি অক্ষর উপসর্গ থেকে শুরু করে।

+-----+--------+
| cnt | prefix |
+-----+--------+
| 794 | Schaa  |
| 758 | Mande  |
| 711 | Schwa  |
| 562 | Angel  |
| 561 | Gecse  |
| 555 | Delgr  |
| 550 | Berna  |
| 547 | Peter  |
| 543 | Cappe  |
| 539 | Stran  |
| 534 | Canna  |
| 485 | Georg  |
| 417 | Neima  |
| 398 | Petti  |
| 398 | Duclo  |
+-----+--------+
15 rows in set (0.55 sec)

প্রতিটি উপসর্গের আরও অনেকগুলি উপস্থিতি রয়েছে যার অর্থ পূর্ববর্তী উদাহরণের মতো মানগুলি প্রায় সমান না হওয়া পর্যন্ত আমাদের N সংখ্যা বৃদ্ধি করতে হবে।

এখানে এন = 9 এর ফলাফল রয়েছে

select count(*) as cnt, left(last_name,9) as prefix from employees group by prefix order by cnt desc limit 0,15;

+-----+-----------+
| cnt | prefix    |
+-----+-----------+
| 336 | Schwartzb |
| 226 | Baba      |
| 223 | Coorg     |
| 223 | Gelosh    |
| 222 | Sudbeck   |
| 222 | Farris    |
| 221 | Adachi    |
| 220 | Osgood    |
| 218 | Mandell   |
| 218 | Neiman    |
| 218 | Masada    |
| 217 | Wendorf   |
| 217 | Boudailli |
| 216 | Cummings  |
| 216 | Pettis    |
+-----+-----------+

এখানে এন = 10 এর ফলাফল রয়েছে।

+-----+------------+
| cnt | prefix     |
+-----+------------+
| 226 | Baba       |
| 223 | Coorg      |
| 223 | Gelosh     |
| 222 | Sudbeck    |
| 222 | Farris     |
| 221 | Adachi     |
| 220 | Osgood     |
| 218 | Mandell    |
| 218 | Neiman     |
| 218 | Masada     |
| 217 | Wendorf    |
| 217 | Boudaillie |
| 216 | Cummings   |
| 216 | Pettis     |
| 216 | Solares    |
+-----+------------+
15 rows in set (0.56 sec)

এটি খুব ভাল ফলাফল। এর অর্থ এই যে আমরা কলামে সূচক করতে পারেন LAST_NAME শুধুমাত্র প্রথম 10 অক্ষর ইন্ডেক্স সঙ্গে। সারণীতে সংজ্ঞা কলাম LAST_NAME হিসাবে সংজ্ঞায়িত করা হয় VARCHAR(16), এবং এই মাধ্যম আমরা 6 বাইট সংরক্ষণ করেছেন (বা আরো যদি গত নামে UTF8 হওয়া অক্ষর) এন্ট্রি প্রতি। এই টেবিলটিতে 1679 স্বতন্ত্র মানগুলি 9 বাইট দ্বারা 6 বাইট দ্বারা গুণিত হয় এবং কল করুন যে এই সংখ্যাটি কীভাবে বাড়বে যদি আমাদের টেবিলটিতে কয়েক মিলিয়ন সারি থাকে।

আপনি আমার পোস্টে মাইএসকিউএলে প্রিফিক্সড ইনডেক্সগুলিতে এন নম্বর গণনা করার অন্যান্য উপায়গুলি পড়তে পারেন ।

সূচকযুক্ত হওয়া উচিত এমন মান উত্পন্ন করতে MD5 এবং SHA1 ফাংশন ব্যবহার করাও ভাল পন্থা নয় । কেন? এটি পোস্টে পড়ুন কীভাবে মাইএসকিউএল ডাটাবেসে একটি প্রাথমিক কী জন্য সঠিক তথ্য টাইপ চয়ন করতে হয়


এটি একটি পৃথক প্রশ্নের খুব ভার্জিক উত্তর।
মোস্তাকাসিও

1
তুমি কি আমার সাথে মজা করছো?
মিঃ এম

আপনি কী ভুল তা ব্যাখ্যা করতে পারেন, বা কোনটি প্রয়োগ করা যায় না?
মিঃ এম

2
আরে মিঃ আমি আসলে আপনার উত্তর পছন্দ। কেন? আমার পুরানো উত্তরে, আমি # 1: পরামর্শে বলেছি If you index like this, you can either look for the whole string or do left-oriented LIKE searches। আমি প্রস্তাব # 3: এও বলেছি If you are looking for one specific value and those values could be lengths well beyond 32 characters, you could store the hash value:। আপনার উত্তরটি পর্যাপ্তরূপে প্রমাণ করে যে একজনকে কেন বিশাল কীগুলি ব্যবহার করা উচিত নয় এবং বামতম অক্ষরে সূচি দেওয়া উচিত, যা পারফরম্যান্সে পার্থক্য আনতে পারে। আপনার উত্তর এখানে। আপনার উত্তরের জন্য +1 এবং ডিবিএ স্ট্যাকএক্সচেঞ্জে স্বাগতম।
রোল্যান্ডোমাইএসকিউএলডিবিএ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.