মাইএসকিউএলে কীভাবে শর্তসাপেক্ষ সূচক তৈরি করবেন?


24

মাইএসকিউএলে সারণির একটি নির্দিষ্ট পরিসর বা উপসেটটি ফিল্টার করার জন্য একটি সূচক কীভাবে তৈরি করবেন? এএফআইএকে সরাসরি তৈরি করা অসম্ভব তবে আমি মনে করি এই বৈশিষ্ট্যটি অনুকরণ করা সম্ভব।

উদাহরণ: আমি NAMEসারিগুলির সাথে কলামের জন্য একটি সূচক তৈরি করতে চাইSTATUS = 'ACTIVE'

এই কার্যকারিতাটি এসকিউএল সার্ভারে একটি ফিল্টার সূচক এবং পোস্টগ্রিসে একটি আংশিক সূচক বলা হবে ।

উত্তর:


9

মাইএসকিউএল বর্তমানে শর্তসাপেক্ষ সূচিগুলি সমর্থন করে না।

আপনি যা জিজ্ঞাসা করছেন তা অর্জন করার জন্য (আপনার এটি করা উচিত নয়;)) আপনি সহায়ক টেবিল তৈরি শুরু করতে পারেন:

CREATE TABLE  `my_schema`.`auxiliary_table` (
   `id` int unsigned NOT NULL,
   `name` varchar(250), /* specify the same way as in your main table */
   PRIMARY KEY (`id`),
   KEY `name` (`name`)
);

তারপরে আপনি প্রধান টেবিলটিতে তিনটি ট্রিগার যুক্ত করুন:

delimiter //

CREATE TRIGGER example_insert AFTER INSERT ON main_table
FOR EACH ROW
BEGIN
   IF NEW.status = 'ACTIVE' THEN
      REPLACE auxiliary_table SET
         auxiliary_table.id = NEW.id,
         auxiliary_table.name = NEW.name;
   END IF;
END;//

CREATE TRIGGER example_update AFTER UPDATE ON main_table
FOR EACH ROW
BEGIN
   IF NEW.status = 'ACTIVE' THEN
      REPLACE auxiliary_table SET
         auxiliary_table.id = NEW.id,
         auxiliary_table.name = NEW.name;
   ELSE
      DELETE FROM auxiliary_table WHERE auxiliary_table.id = OLD.id;
   END IF;
END;//

CREATE TRIGGER example_delete AFTER DELETE ON main_table
FOR EACH ROW
BEGIN
   DELETE FROM auxiliary_table WHERE auxiliary_table.id = OLD.id;
END;//

delimiter ;

আমাদের দরকার delimiter //কারণ আমরা ;ট্রিগারগুলির ভিতরে ব্যবহার করতে চাই ।

এইভাবে, সহায়ক টেবিলটিতে মূল সারণী সারিগুলিতে ঠিক আইডি থাকবে যা "ACTIVE" স্ট্রিংটি যুক্ত করে, ট্রিগারগুলি আপডেট করে।

এটি ব্যবহার selectকরতে, আপনি সাধারণটি ব্যবহার করতে পারেন join:

SELECT main_table.* FROM auxiliary_table LEFT JOIN main_table
   ON auxiliary_table.id = main_table.id
   ORDER BY auxiliary_table.name;

যদি প্রধান টেবিলটিতে ইতিমধ্যে ডেটা রয়েছে, বা আপনি যদি এমন কিছু বাহ্যিক ক্রিয়া করেন যা ডেটাটিকে একটি অস্বাভাবিক উপায়ে পরিবর্তন করে (EG: MySQL এর বাইরে), আপনি এটি সহ সহায়ক টেবিলটি ঠিক করতে পারেন:

INSERT INTO auxiliary_table SET
   id = main_table.id,
   name = main_table.name,
   WHERE main_table.status="ACTIVE";

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


7

যদি আমি প্রশ্নটি সঠিকভাবে বুঝতে পারি তবে আমার মনে হয় আপনি যা করতে চেষ্টা করছেন তা হ'ল নাম এবং স্ট্যাটাস উভয় কলামে একটি সূচক তৈরি করা। এটি আপনাকে দক্ষতার সাথে জিজ্ঞাসা করার অনুমতি দেবে যে কোথায় NAME = 'স্মিথ' এবং STATUS = 'ক্রিয়াকলাপ'


1
ঠিক আছে, তবে আপনার যদি ACTIVE অবস্থা সহ তুলনামূলকভাবে কয়েকটি লাইন থাকে তবে এটি স্থান দক্ষ নয়।
ম্যানেরো

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

এবং ডিস্কের স্থানটি সস্তা ...
ব্ল্যাকইসিস

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

আমি স্মৃতিতেও দ্বিমত পোষণ করব, আজকের দিনগুলিতে এটিও বেশ সস্তা (অবশ্যই ডিস্কের জায়গার মতো সস্তা নয়, তবে এর
কিছুটির

6

আপনি শর্তসাপেক্ষ সূচক করতে পারবেন না, তবে উদাহরণস্বরূপ, আপনি ( name, status) উপর একটি বহু-কলাম সূচী যুক্ত করতে পারেন ।

যদিও এটি those কলামগুলির সমস্ত ডেটা সূচী করবে, এটি এখনও "সক্রিয়" স্থিতি সহ আপনি যে নামগুলি সন্ধান করছেন তা সন্ধান করতে সহায়তা করবে।


4

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

দুর্ভাগ্যক্রমে অন্তর্নির্মিত টেবিল পার্টিশন বৈশিষ্ট্যটি আপনাকে আপনার সন্ধানে সহায়তা করবে না কারণ আপনি একক পার্টিশনে সূচি প্রয়োগ করতে পারবেন না।

আপনি একটি সূচক সহ একটি অতিরিক্ত কলাম বজায় রাখতে পারেন এবং কেবলমাত্র সেই কলামে একটি মান থাকতে পারে যখন আপনি চান যে সূচকটি ভিত্তিক হয়ে উঠতে চান তবে এটি শ্রম নিবিড় এবং সীমিত (বা নেতিবাচক) মানের ক্ষেত্রে হতে পারে ক্যোয়ারী দক্ষতা এবং স্থান সঞ্চয়।


আরও ভাল ইনডেক্সিংয়ের জন্য আমার কাছে দুটি টেবিল থাকবে না, কারণ যোগদানটি এখনও ব্যয়বহুল হবে না?
jcolebrand

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

0

মাইএসকিউএল এখন ভার্চুয়াল কলাম আছে, যা সূচকগুলির জন্য ব্যবহার করা যেতে পারে।


3
ফিল্টারড ইনডেক্স অনুকরণে এই বৈশিষ্ট্যটি কীভাবে ব্যবহার করা যেতে পারে?
ypercubeᵀᴹ

1
@ ইয়ার-ট্রোলᵀᴹ, ড্রুড 62 ওরাকল সম্পর্কে ভাবতে পারে: dbfiddle.uk/… - মাইএসকিউএল যদিও NULLs সাথে একইভাবে আচরণ করতে দেখেনি: dbfiddle.uk/…
জ্যাক ডগলাস

@ জ্যাকডুগলাস সম্ভবত (এটি কি কেবল একটি সূচক অপটিমাইজেশন নয় যা উপায় দ্বারা স্থান সঞ্চয় করে? অন্য কথায় select count(*) from foo where id is null ;কোনও সূচক ব্যবহার করতে পারে?)
ypercubeᵀᴹ

@ ইয়াপার-ট্রোলᵀᴹ ওরাকল সারিগুলি সারণি করে না যেখানে সমস্ত ইনডেক্সড কলামগুলি নুল হয় ( Use-theindind-luke.com/sql/where-clause/null/index ) - এবং ভার্চুয়াল কলামটি decode(status,'ACTIVE',name,null)উদাহরণ হিসাবে থাকতে পারে ।
জ্যাক ডগলাস

থানেক্স, আমি ভেবেছিলাম যে সাম্প্রতিক সংস্করণগুলিতে পরিবর্তিত হয়েছে (এবং নালগুলি সূচকযুক্ত করা হয়েছিল)।
ypercubeᵀᴹ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.