আমি নিম্নলিখিত পরিস্থিতির জন্য টেবিল / সূচী নকশার জন্য পরামর্শ খুঁজছি:
আমার কাছে একটি বড় টেবিল (স্টক প্রাইস হিস্ট্রি ডেটা, ইনোডিবি, ৩৫ মিলিয়ন সারি এবং ক্রমবর্ধমান) রয়েছে একটি যৌগিক প্রাথমিক কী (একত্রিত (ইনট), তারিখ (তারিখ))। দামের তথ্য ছাড়াও, আমার 200 টি দ্বিগুণ মান রয়েছে যা প্রতিটি রেকর্ডের সাথে সামঞ্জস্য করা প্রয়োজন।
CREATE TABLE `mytable` (
`assetid` int(11) NOT NULL,
`date` date NOT NULL,
`close` double NOT NULL,
`f1` double DEFAULT NULL,
`f2` double DEFAULT NULL,
`f3` double DEFAULT NULL,
`f4` double DEFAULT NULL,
... skip a few …
`f200` double DEFAULT NULL,
PRIMARY KEY (`assetid`, `date`)) ENGINE=`InnoDB` DEFAULT CHARACTER SET latin1 COLLATE
latin1_swedish_ci ROW_FORMAT=COMPACT CHECKSUM=0 DELAY_KEY_WRITE=0
PARTITION BY RANGE COLUMNS(`date`) PARTITIONS 51;
আপডেট এবং পুনরুদ্ধারের সহজতার জন্য আমি প্রথমে 200 টি ডাবল কলামগুলি সরাসরি এই টেবিলটিতে সঞ্চিত করেছি এবং এটি ভাল কাজ করে যাচ্ছিল, কারণ এই টেবিলের একমাত্র অনুসন্ধানটি একত্রিত এবং তারিখ দ্বারা করা হয়েছিল (এগুলি এই টেবিলের বিপরীতে যে কোনও প্রশ্নের সাথে ধর্মীয়ভাবে অন্তর্ভুক্ত রয়েছে) ), এবং 200 ডাবল কলামগুলি কেবল পঠিত ছিল। আমার ডাটাবেসের আকার 45 গিগের কাছাকাছি ছিল
তবে, এখন আমার প্রয়োজনীয়তা রয়েছে যেখানে এই 200 টি কলামের (f1, f2, ... f200 নামকরণ করা হয়েছে) যেকোন সংমিশ্রণ দ্বারা আমার এই টেবিলটি জিজ্ঞাসা করতে সক্ষম হওয়া প্রয়োজন:
select from mytable
where assetid in (1,2,3,4,5,6,7,....)
and date > '2010-1-1' and date < '2013-4-5'
and f1 > -0.23 and f1 < 0.9
and f117 > 0.012 and f117 < .877
etc,etc
historতিহাসিকভাবে আমি এর আগে এই প্রচুর পরিমাণে ডেটা নিয়ে কাজ করতে পারি নি, তাই আমার প্রথম প্রবৃত্তিটি ছিল যে এই 200 টি কলামের প্রত্যেকটিতে সূচকের প্রয়োজন ছিল, বা আমি বড় টেবিল স্ক্যানগুলি দিয়ে শেষ করে দেব me আমার কাছে প্রাথমিক কী, মান এবং মানগুলি সূচী সহ 200 টি কলামের জন্য একটি সারণী প্রয়োজন। সুতরাং আমি যে সঙ্গে গিয়েছিলাম।
CREATE TABLE `f1` (
`assetid` int(11) NOT NULL DEFAULT '0',
`date` date NOT NULL DEFAULT '0000-00-00',
`value` double NOT NULL DEFAULT '0',
PRIMARY KEY (`assetid`, `date`),
INDEX `val` (`value`)
) ENGINE=`InnoDB` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ROW_FORMAT=COMPACT CHECKSUM=0 DELAY_KEY_WRITE=0;
আমি সমস্ত 200 টেবিলগুলি পূরণ করেছি এবং তালিকাবদ্ধ করেছি। আমি সমস্ত 200 কলামের সাথে প্রধান টেবিলটি অক্ষত রেখেছি, নিয়মিত হিসাবে এটি জমা দেওয়া এবং তারিখের সীমাটি অনুসন্ধান করা হয় এবং সমস্ত 200 কলাম নির্বাচন করা হয়। আমি অনুভব করেছি যে পড়ার উদ্দেশ্যে সেই কলামগুলি প্যারেন্ট সারণীতে (আনইনডেক্সেড) রেখে দেওয়া এবং তারপরে তাদের নিজস্ব টেবিলগুলিতে তালিকাবদ্ধ করা (ফিল্টারিংয়ের জন্য যোগদানের জন্য) হবে সবচেয়ে পারফরম্যান্স। আমি জিজ্ঞাসার নতুন ফর্মটি সম্পর্কে দৌড়েছি
select count(p.assetid) as total
from mytable p
inner join f1 f1 on f1.assetid = p.assetid and f1.date = p.date
inner join f2 f2 on f2.assetid = p.assetid and f2.date = p.date
where p.assetid in(1,2,3,4,5,6,7)
and p.date >= '2011-01-01' and p.date < '2013-03-14'
and(f1.value >= 0.96 and f1.value <= 0.97 and f2.value >= 0.96 and f2.value <= 0.97)
প্রকৃতপক্ষে আমার কাঙ্ক্ষিত ফলাফলটি অর্জন করা হয়েছিল, আমাকে ব্যাখ্যা করুন যে স্ক্যান করা সারিগুলি এই কোয়েরির জন্য অনেক ছোট। তবে আমি কিছু অবাঞ্ছিত পার্শ্ব প্রতিক্রিয়া দ্বারা ক্ষতবিক্ষত।
1) আমার ডাটাবেস 45 গিগ থেকে 110 গিগে গিয়েছিল। আমি আর ডিবি আর র্যামে রাখতে পারি না। (তবে আমার পথে 256 জিগ র্যাম রয়েছে)
২) নতুন ডেটাতে রাতের সন্নিবেশগুলি এখন একবারের পরিবর্তে 200 বার করা দরকার
3) নতুন 200 টেবিলগুলির রক্ষণাবেক্ষণ / ডিফ্র্যাগটি কেবল 1 টি টেবিলের চেয়ে 200 গুণ বেশি সময় নেয়। এটি একটি রাতে সম্পন্ন করা যায় না।
4) এফ 1, ইত্যাদি টেবিলগুলির বিরুদ্ধে প্রশ্নগুলি অগত্যা সম্পাদনকারী নয়। উদাহরণ স্বরূপ:
select min(value) from f1
where assetid in (1,2,3,4,5,6,7)
and date >= '2013-3-18' and date < '2013-3-19'
উপরের ক্যোয়ারীটি ব্যাখ্যা করার সময় দেখায় যে এটি <1000 টি সারিতে দেখায়, সম্পূর্ণ হতে 30+ সেকেন্ড সময় নিতে পারে। আমি ধরে নিলাম এটি কারণ সূচকগুলি মেমরির সাথে ফিট করার জন্য খুব বড়।
যেহেতু এটি খুব খারাপ সংবাদ ছিল, তাই আমি আরও তাকাতে পারলাম এবং বিভাজন দেখতে পেলাম। আমি প্রধান টেবিলে পার্টিশনগুলি প্রয়োগ করেছি, প্রতি 3 মাস অন্তর বিভাজনে। মাসিকটি আমার কাছে বোধগম্য মনে হয়েছিল তবে আমি পড়েছি যে একবার আপনি 120 টি পার্টিশন বা তার বেশি পেয়ে গেলে পারফরম্যান্স ক্ষতিগ্রস্থ হয়। ত্রৈমাসিকের বিভাজন আমাকে পরবর্তী ২০ বছর বা তারও বেশি সময় ধরে রাখবে। প্রতিটি পার্টিশন 2 গিগের নিচে থাকে। আমি পার্টিশনগুলি ব্যাখ্যা করলাম এবং সবকিছু সঠিকভাবে ছাঁটাই হচ্ছে বলে মনে হচ্ছে, তাই নির্বিশেষে / অপ্টিমাইজ / মেরামত করার উদ্দেশ্যে খুব কমপক্ষে পার্টিশনটি একটি ভাল পদক্ষেপ ছিল বলে মনে করি।
এই নিবন্ধটি নিয়ে আমি বেশ ভাল সময় ব্যয় করেছি
http://ftp.nchu.edu.tw/MySQL/tech-resources/articles/testing-partitions-large-db.html
আমার টেবিলটি বর্তমানে প্রাথমিক কী সহ এখনও বিভাজনিত। নিবন্ধটিতে উল্লেখ করা হয়েছে যে প্রাথমিক কীগুলি একটি বিভাজনযুক্ত টেবিলকে ধীর করতে পারে, তবে আপনার যদি এমন কোনও মেশিন থাকে যা এটি পরিচালনা করতে পারে তবে পার্টিশনযুক্ত টেবিলের প্রাথমিক কীগুলি দ্রুততর হবে। পথে আমার কাছে একটি বড় মেশিন রয়েছে তা জেনে (256 জি র্যাম), আমি কীগুলি রেখে দিয়েছি।
আমি এটি দেখতে হিসাবে, এখানে আমার বিকল্প আছে
বিকল্প 1
1) অতিরিক্ত 200 টেবিলগুলি সরিয়ে ফেলুন এবং এফ 1, এফ 2 ইত্যাদি মান সন্ধানের জন্য ক্যোরিটিকে টেবিল স্ক্যান করতে দিন। অ-অনন্য সূচকগুলি যথাযথভাবে পার্টিশনযুক্ত টেবিলের কার্য সম্পাদনকে আঘাত করতে পারে। ব্যবহারকারীর ক্যোয়ারী চালানোর আগে একটি ব্যাখ্যা চালান এবং স্ক্যান করা সারিগুলির সংখ্যা আমি সংজ্ঞায়িত কিছু থ্রোহোল্ডের বেশি হলে তাদের অস্বীকার করুন। নিজেকে দানবীয় ডাটাবেসের ব্যথা বাঁচান। হেক, এগুলি যেভাবেই হোক খুব শীঘ্রই স্মৃতিতে থাকবে।
উপ-প্রশ্ন:
এটি কি মনে হচ্ছে যে আমি একটি উপযুক্ত পার্টিশন স্কিমটি বেছে নিয়েছি?
বিকল্প 2
একই 3 মাসের স্কিম ব্যবহার করে সমস্ত 200 টেবিল ভাগ করুন। আরও ছোট সারি স্ক্যানগুলি উপভোগ করুন এবং ব্যবহারকারীদের আরও বড় ক্যোরি চালানোর অনুমতি দিন। এখন যেহেতু তারা পার্টিশন করা হয়েছে কমপক্ষে আমি তাদের রক্ষণাবেক্ষণের জন্য একসাথে 1 পার্টিশন পরিচালনা করতে পারি। হেক, এগুলি যেভাবেই হোক খুব শীঘ্রই স্মৃতিতে থাকবে। রাতের বেলা সেগুলি আপডেট করার দক্ষ উপায় তৈরি করুন।
উপ-প্রশ্ন:
আপনি কি কোনও কারণ দেখেন যে আমি জিজ্ঞাসা করার সময় আমি সর্বদা একত্রিত হয়েছি এবং তারিখ জেনেও এই f1, f2, f3, f4 ... টেবিলগুলিতে প্রাথমিক কী সূচকগুলি এড়াতে পারি? আমার কাছে এটিকে স্বজ্ঞাত মনে হয় তবে আমি এই আকারের ডেটা সেটগুলিতে অভ্যস্ত নই। এটি ডাটাবেসটি সঙ্কুচিত করবে যা আমি ধরে নিচ্ছি
বিকল্প 3
সেই স্থানটি পুনরায় দাবি করতে মাস্টার সারণীতে f1, f2, f3 কলামগুলি ফেলে দিন। আমার যদি 200 টি বৈশিষ্ট্য পড়ার দরকার হয় তবে 200 সাথে যোগ দিন, সম্ভবত এটি যতটা শোনায় তত ধীর হবে না।
বিকল্প 4
আমি এতক্ষণ যা ভাবি তার থেকে আপনার কাঠামোর আরও ভাল উপায় আছে।
* দ্রষ্টব্য: শীঘ্রই আমি প্রতিটি আইটেমের মধ্যে এই দ্বিগুণ মানগুলির আরও 50-100 যুক্ত করব, সুতরাং আসন্নটি বোধ করে আমার ডিজাইন করা দরকার need
যেকোনো এবং সকল সাহায্যর জন্য ধন্যবাদ
আপডেট # 1 - 3/24/2013
আমি নীচে পেয়ে যাওয়া মন্তব্যে প্রস্তাবিত ধারণার সাথে গিয়েছিলাম এবং নিম্নলিখিত সেটআপের সাথে একটি নতুন টেবিল তৈরি করেছি:
create table 'features'{
assetid int,
date date,
feature varchar(4),
value double
}
আমি 3 মাসের ব্যবধানে টেবিলটি বিভক্ত করেছি।
আমি আগের 200 টি টেবিলগুলি উড়িয়ে দিয়েছি যাতে আমার ডাটাবেসটি 45 গিগের নিচে ফিরে আসে এবং এই নতুন সারণীটি পূরণ করা শুরু করে। দেড় দিন পরে, এটি সম্পন্ন হয়েছে, এবং আমার ডাটাবেসটি এখন একটি নিটোল 220 জিগ-এ বসে আছে !
এটি মাস্টার টেবিল থেকে এই 200 টি মানগুলি সরিয়ে ফেলার সম্ভাবনাটিকে মঞ্জুরি দেয়, কারণ আমি এগুলিকে একটির সাথে যোগ দিতে পারি, তবে এটি কেবল আমাকে 25 গিগ বা আরও কিছু দিতে পারে
আমি এটিকে একত্রিত, তারিখ, বৈশিষ্ট্য এবং মূল্য অনুসারে একটি সূচক কী তৈরি করতে বলেছিলাম, এবং 9 ঘন্টা চুগিংয়ের পরে এটি সত্যিই একটি দাঁত তৈরি করে নি এবং জমে যায় বলে মনে হয়েছিল তাই আমি সেই অংশটি বন্ধ করে দিয়েছি।
আমি কয়েকটি পার্টিশন পুনর্নির্মাণ করেছি তবে এটি খুব বেশি / কোনও স্থান পুনরায় দাবি করতে পারে বলে মনে হচ্ছে না।
সুতরাং সমাধানটি দেখে মনে হচ্ছে এটি সম্ভবত আদর্শ হবে না। আমি যে আশ্চর্যজনক কলামগুলির চেয়ে সারিগুলি উল্লেখযোগ্যভাবে বেশি স্থান নিয়েছি, সে কারণেই কেন এই সমাধানটি এত বেশি স্থান নিয়েছিল?
আমি এই নিবন্ধটি জুড়ে এসেছি:
http://www.chrismoos.com/2010/01/31/mysql-partitioning-tables-with-millions-of-rows
এটা আমাকে একটি ধারণা দিয়েছে। এটা বলে:
প্রথমদিকে, আমি তারিখ অনুসারে RANGE পার্টিশন সম্পর্কে চিন্তা করেছিলাম এবং আমার প্রশ্নগুলিতে তারিখটি ব্যবহার করার সময়, কোনও ক্যোয়ারির জন্য খুব বড় তারিখের সীমা থাকা খুব সাধারণ বিষয়, এবং এর অর্থ এটি সহজেই সমস্ত পার্টিশন বিস্তৃত করতে পারে।
এখন আমি তারিখ অনুসারে বিভাজনও করছি, তবে বড় তারিখের সীমা অনুসারে অনুসন্ধানের অনুমতি দিচ্ছি যা আমার বিভাজনের কার্যকারিতা হ্রাস করবে। আমি অনুসন্ধান করার সময় আমার সর্বদা একটি তারিখের সীমা থাকবে, তবে আমার কাছে সর্বদা সমাবেশগুলির একটি তালিকা থাকবে। সম্ভবত আমার সমাধানটি একত্রিত ও তারিখ দ্বারা বিভাজন হওয়া উচিত, যেখানে আমি সাধারণত অনুসন্ধান করা একত্রিত রেঞ্জগুলি সনাক্ত করি (যা আমি সামনে আসতে পারি, সেখানে স্ট্যান্ডার্ড তালিকাগুলি, এসএন্ডপি 500, রাসেল 2000, ইত্যাদি) রয়েছে। এইভাবে আমি প্রায় কখনই পুরো ডেটা সেটটির দিকে তাকাব না।
তারপরে আবারও, আমি একত্রিত হয়ে যাই হোক না কেন তারিখের ভিত্তিতে প্রাইমারী, তাই সম্ভবত এটি খুব বেশি সাহায্য করবে না।
আরও কোন চিন্তা / মন্তব্য প্রশংসা করা হবে।
(value_name varchar(20), value double)
দোকান সবকিছু করতে সক্ষম হবে (value_name
হচ্ছেf1
,f2
, ...)