বৃহত্তর ডেটাসেটের উপর ঘন্টা ধরে গ্রুপ করুন


12

এমএস এসকিউএল ২০০৮ ব্যবহার করে আমি 2.5 মিলিয়ন রেকর্ড থেকে গড় ক্ষেত্রটি নির্বাচন করছি। প্রতিটি রেকর্ড এক সেকেন্ড উপস্থাপন করে। মাইফিল্ড সেই 1 সেকেন্ড রেকর্ডের প্রতি ঘন্টা গড়ে। অবশ্যই সার্ভার সিপিইউ 100% হিট করেছে এবং নির্বাচনটি খুব বেশি সময় নেয়। আমার সম্ভবত সেই গড় মূল্যগুলি সংরক্ষণ করতে হবে যাতে প্রতিটি অনুরোধে এসকিউএলকে সেই সমস্ত রেকর্ড নির্বাচন করতে না হয়। কি করা যেতে পারে?

  SELECT DISTINCT
         CONVERT(VARCHAR, [timestamp], 1)+' '+ CAST(DATEPART(Hh,[timestamp]) as VARCHAR) AS TimeStampHour,
         MIN([timestamp]) as TimeStamp,
         AVG(MyField) As AvgField
    FROM MyData
   WHERE TimeStamp > '4/10/2011'
GROUP BY CONVERT(VARCHAR, [timestamp], 1)+' '+ CAST(DATEPART(Hh,[timestamp]) as VARCHAR)
ORDER BY TimeStamp

6
টাইমস্ট্যাম্প কি ক্লাস্টারড ইনডেক্সের অংশ? এটি হওয়া উচিত ...

@ আনিসানিটি - কেন? তিনি সিপিইউ নয় ডিস্ক আইও
বেরিয়েছেন

উত্তর:


5

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

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

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

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

একটি পদ্ধতি যে নাআপনার ডেটাটিকে অস্বীকৃতি জানাতে হবে, তবে অতিরিক্ত কাঠামোর প্রয়োজন নেই, "সময় সারণী" ব্যবহার করা উচিত, এক্ষেত্রে আপনি যে সমস্ত সময় বিবেচনা করবেন তার জন্য প্রতি ঘন্টায় এক সারি রয়েছে। এই টেবিলটি একটি ডিবি বা প্রশংসনীয় আকারে উল্লেখযোগ্য পরিমাণে স্থান গ্রহণ করবে না - 100 বছরের একটি টাইমস্প্যানটি কাটাতে একটি টেবিলে দুটি তারিখের এক সারি (ঘন্টার শুরু এবং শেষের মতো, যেমন '2011-01-01 @ 00: 00: 00.0000 ',' 2011-01-01 @ 00: 00: 59.9997 ', "9997" একটি স্বল্প সংখ্যক মিলসেকেন্ডের একটি ডেটটাইম ক্ষেত্রটি পরের দ্বিতীয় পর্যন্ত গোল করবে না) যা উভয় অংশের অংশ ক্লাস্টারড প্রাথমিক কীটি M 14Mbyte স্পেস নেবে (প্রতি সারিতে 8 + 8 বাইট * ২৪ ঘন্টা / দিন * ৩5৫.২৫ দিন / বছর * ১০০, এবং ক্লাস্টারড ইনডেক্সের গাছ কাঠামোর ওভারহেডের জন্য কিছুটা হলেও এটি ওভারহেডটি গুরুত্বপূর্ণ হবে না) ।

SELECT CONVERT(VARCHAR, [timestamp], 1)+' '+ CAST(DATEPART(Hh,[timestamp]) as VARCHAR) AS TimeStampHour
     , MIN([timestamp]) as TimeStamp
     , AVG(MyField) As AvgField
FROM TimeRangeByHours tt
INNER JOIN MyData md ON md.TimeStamp BETWEEN tt.StartTime AND tt.EndTime
WHERE tt.StartTime > '4/10/2011'
GROUP BY tt.StartTime
ORDER BY tt.StartTime

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

আপনার বর্তমান পরিস্থিতি এবং গণিত কলাম সমাধানের তুলনায় টাইম টেবিল পদ্ধতির একটি অতিরিক্ত পার্থক্য রয়েছে (এটি বেশ সুবিধাজনক হতে পারে): এটি উপরের উদাহরণের ক্যোয়ারিতে কেবলমাত্র অন্তর্গত জয়েন পরিবর্তন করে কোনও সময়ের জন্য কোন ডেটা নেই এমন সময়কালের জন্য সারিগুলি ফিরিয়ে দিতে পারে it একটি বাম আউটর হতে।

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

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


3

এই প্রশ্নটি দেখুন ( একটি তারিখের মেঝেতে ) এছাড়াও, কেন সমস্ত কিছুকে স্ট্রিংয়ে রূপান্তর করতে বিরক্ত করবেন - আপনি পরে এটি করতে পারেন (যদি আপনার প্রয়োজন হয়)।

  SELECT DISTINCT
         dateadd(hour,datediff(hour,0,[timestamp]),0) AS TimeStampHour,
         MIN([timestamp]) as TimeStamp,
         AVG(MyField) As AvgField
    FROM MyData
   WHERE TimeStamp > '4/10/2011'
GROUP BY dateadd(hour,datediff(hour,0,[timestamp],0);
ORDER BY TimeStamp

1

আপনি কি ক্যোয়ারীটি দ্রুত তৈরি করতে চান বা আপনি কীভাবে ডেটা স্ন্যাপশট তৈরি করবেন এবং এটি সংরক্ষণ করবেন তা জিজ্ঞাসা করছেন?

আপনি যদি এটি আরও দ্রুত করতে চান তবে আপনার অবশ্যই টাইমস্ট্যাম্প ক্ষেত্রের একটি সূচক প্রয়োজন। এছাড়াও, আমি এটি ঘন্টাকে রূপান্তর করতে ব্যবহার করার পরামর্শ দেব:

select convert(varchar(13), getdate(), 121)

আপনার যদি কোনও স্ন্যাপশট insert intoতৈরি করতে হয় এবং এটি পুনরায় ব্যবহার করতে হয় তবে আপনার ক্যোয়ারির ফলাফলগুলি সহ একটি নতুন টেবিল তৈরি করতে ব্যবহার করুন । সূচি সারণী অনুসারে এবং এটি ব্যবহার করুন। আমি যা বুঝি তার থেকে আপনার টাইমস্ট্যাম্পঅওয়ারে একটি সূচি প্রয়োজন।

এছাড়াও আপনি এমন একটি কাজ সেটআপ করতে পারেন যা আপনার নতুন সামগ্রিক টেবিলটিতে প্রতিদিনের ডেটা একত্রিত করে।


-1

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


1
-1 - না আপনি "এটি ডাটাবেসের প্রতিটি একক সারিতে বিনা মূল্যে হিট করছেন" - কোনও সূচক TimeStampএখনও সারিগুলি ফিল্টার করার জন্য ব্যবহৃত হবে
জ্যাক বলেছেন টপান্সওয়ার্স.অক্সিজ 7:31

-3

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

আপনার যদি অর্থ থাকে তবে আপনি কোনও ডেডিকেটেড প্রক্রিয়া ডেটা ইতিহাসবিদ কেনার বিষয়টি বিবেচনা করতে পারেন:

  1. হানিওয়েল ইউনিফর্মেন্স পিএইচডি
  2. ওসিসফট পি.আই.
  3. অ্যাস্পেনটেক আইপি 21
  4. প্রভৃতি

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

.. এবং একটি সাধারণ নোটে: DISTINCTএসকিউএল লেখার সময় আমি সর্বদা কীওয়ার্ডটি ব্যবহার এড়াতে চেষ্টা করি । এটি কখনও কখনও একটি ভাল ধারণা। আপনার ক্ষেত্রে আপনার ক্লজটি DISTINCTযুক্ত MIN([timestamp])করে আপনার ড্রপ করতে এবং একই ফলাফল পেতে সক্ষম হওয়া উচিত GROUP BY


1
এটি সত্যই সঠিক নয়। একটি রিলেশনাল ডাটাবেস 2.5 মিলিয়ন রেকর্ডের জন্য পুরোপুরি জরিমানা। এমনকি তিনি অনেকগুলি টেবিল জুড়েও যোগ দিচ্ছেন না। আপনি যখন আপনার ডেটাটিকে অস্বীকৃতি জানাতে বা অ-সম্পর্কমূলক সিস্টেমে চলে যাওয়ার দরকার হয় তার প্রথম ইঙ্গিতটি যখন আপনি অনেকগুলি টেবিল জুড়ে জটিল, যোগ দেয়। পোস্টারের ডেটা সেটটি আসলে একটি রিলেশনাল ডাটাবেস সিস্টেমের একদম গ্রহণযোগ্য ব্যবহারের মতো মনে হচ্ছে।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.