আমি কীভাবে প্রথম 100 মিলিয়ন ইতিবাচক পূর্ণসংখ্যাকে স্ট্রিংয়ে রূপান্তর করতে পারি?


13

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

আমি কিছুটা আনুষ্ঠানিক সংজ্ঞা দিয়ে শুরু করার চেষ্টা করব। একটি স্ট্রিং সিরিজটিতে অন্তর্ভুক্ত করা হয় যদি এটি কেবল এ - জেড থেকে মূলধনগুলি নিয়ে থাকে। সিরিজের প্রথম শব্দটি হল "এ"। সিরিজটিতে সমস্ত বৈধ স্ট্রিং থাকে যা দৈর্ঘ্যের অনুসারে বাছাই করা হয় প্রথমে এবং আদর্শ বর্ণানুক্রমিক ক্রম দ্বিতীয় second স্ট্রিংগুলি ডাকা একটি কলামে একটি টেবিলের মধ্যে থাকলে STRING_COL, ক্রমটি টি-এসকিউএল হিসাবে সংজ্ঞায়িত করা যেতে পারে ORDER BY LEN(STRING_COL) ASC, STRING_COL ASC

কম আনুষ্ঠানিক সংজ্ঞা দিতে এক্সেলের বর্ণমালা কলাম শিরোনাম একবার দেখুন a সিরিজ একই প্যাটার্ন। আপনি বিবেচনা করুন কীভাবে আপনি কোনও সংখ্যাকে বেস 26 সংখ্যায় রূপান্তর করতে পারেন:

1 -> এ, 2 -> বি, 3 -> সি, ..., 25 -> ওয়াই, 26 -> জেড, 27 -> এএ, 28 -> এবি, ...

উপমাটি পুরোপুরি নিখুঁত নয় কারণ "এ" বেস টেনের মধ্যে 0 এর চেয়ে আলাদা আচরণ করে। নীচে নির্বাচিত মানগুলির একটি সারণী রয়েছে যা আশা করি এটি আরও স্পষ্ট করে তুলবে:

╔════════════╦════════╗
 ROW_NUMBER  STRING 
╠════════════╬════════╣
          1  A      
          2  B      
         25  Y      
         26  Z      
         27  AA     
         28  AB     
         51  AY     
         52  AZ     
         53  BA     
         54  BB     
      18278  ZZZ    
      18279  AAAA   
     475253  ZZZY   
     475254  ZZZZ   
     475255  AAAAA  
  100000000  HJUNYV 
╚════════════╩════════╝

লক্ষ্যটি এমন একটি SELECTক্যোয়ারী লিখতে হবে যা উপরের সংজ্ঞায়িত ক্রমটিতে প্রথম 100000000 স্ট্রিংগুলি দেয়। আমি এসএসএমএসে ক্যোয়ারী চালিয়ে পরীক্ষার কাজটি টেবিলে সংরক্ষণের বিরোধী হিসাবে বাতিল করে দিয়ে ফলাফলটি বাতিল করে দিয়েছি:

ফলাফল সেট বাতিল

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

উপরে বর্ণিত ডেটা সেটটি দক্ষতার সাথে উত্পাদনের কয়েকটি পদ্ধতি কী কী? মার্টিন স্মিথ উল্লেখ করেছেন যে এতগুলি সারি ওভারহেড প্রসেসিংয়ের কারণে সম্ভবত একটি সিএলআর সঞ্চিত পদ্ধতি সম্ভবত ভাল পদ্ধতির নয়।

উত্তর:


7

আপনার সমাধানটি আমার ল্যাপটপে 35 সেকেন্ডের জন্য চলে । নিম্নলিখিত কোডটি 26 সেকেন্ড সময় নেয় (অস্থায়ী টেবিলগুলি তৈরি এবং পপুলেশন সহ):

অস্থায়ী টেবিলগুলি

DROP TABLE IF EXISTS #T1, #T2, #T3, #T4;

CREATE TABLE #T1 (string varchar(6) NOT NULL PRIMARY KEY);
CREATE TABLE #T2 (string varchar(6) NOT NULL PRIMARY KEY);
CREATE TABLE #T3 (string varchar(6) NOT NULL PRIMARY KEY);
CREATE TABLE #T4 (string varchar(6) NOT NULL PRIMARY KEY);

INSERT #T1 (string)
VALUES
    ('A'), ('B'), ('C'), ('D'), ('E'), ('F'), ('G'),
    ('H'), ('I'), ('J'), ('K'), ('L'), ('M'), ('N'),
    ('O'), ('P'), ('Q'), ('R'), ('S'), ('T'), ('U'),
    ('V'), ('W'), ('X'), ('Y'), ('Z');

INSERT #T2 (string)
SELECT T1a.string + T1b.string
FROM #T1 AS T1a, #T1 AS T1b;

INSERT #T3 (string)
SELECT #T2.string + #T1.string
FROM #T2, #T1;

INSERT #T4 (string)
SELECT #T3.string + #T1.string
FROM #T3, #T1;

সেখানে চারটি চরিত্রের অর্ডারযুক্ত সংমিশ্রণের ধারণাটি এখানে রয়েছে।

প্রধান কোড

SELECT TOP (100000000)
    UA.string + UA.string2
FROM
(
    SELECT U.Size, U.string, string2 = '' FROM 
    (
        SELECT Size = 1, string FROM #T1
        UNION ALL
        SELECT Size = 2, string FROM #T2
        UNION ALL
        SELECT Size = 3, string FROM #T3
        UNION ALL
        SELECT Size = 4, string FROM #T4
    ) AS U
    UNION ALL
    SELECT Size = 5, #T1.string, string2 = #T4.string
    FROM #T1, #T4
    UNION ALL
    SELECT Size = 6, #T2.string, #T4.string
    FROM #T2, #T4
) AS UA
ORDER BY 
    UA.Size, 
    UA.string, 
    UA.string2
OPTION (NO_PERFORMANCE_SPOOL, MAXDOP 1);

এটি হ'ল চারটি প্রাক্কলকুলেটেড টেবিলগুলির একটি সাধারণ অর্ডার-সংরক্ষণ ইউনিয়ন, যার সাথে প্রয়োজনীয় হিসাবে 5-অক্ষর এবং 6-অক্ষরের স্ট্রিং রয়েছে। প্রত্যয় থেকে উপসর্গ পৃথক করা বাছাই করা এড়ানো হয়।

হত্যা পরিকল্পনা

100 মিলিয়ন সারি


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

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


6

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

প্রথম সিদ্ধান্তটি ছিল হেল্পার ডেটা কোথায় সঞ্চয় করা যায়। আমি একটি টেম্প টেবিলটি ব্যবহার করার চেষ্টা করেছি তবে ডেটা একক পৃষ্ঠায় ফিট করার পরেও এটির পারফরম্যান্সে আশ্চর্যজনকভাবে নেতিবাচক প্রভাব পড়ে। টেম্প টেবিলটিতে নীচের ডেটা রয়েছে:

SELECT 'A'
UNION ALL SELECT 'B'
...
UNION ALL SELECT 'Y'
UNION ALL SELECT 'Z'

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

মজার বিষয় হচ্ছে, এসকিউএল সার্ভার একটি একক পৃষ্ঠার টেম্পডিবি টেবিল থেকে আদেশিত ফলাফলগুলি একটি টেবিল স্পুলে অর্ডার করা ডেটা সহ চয়ন করতে পছন্দ করে:

খারাপ স্পোল

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

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

ধ্রুব স্ক্যান অর্ডার

তবে কোনও সম্ভাবনা না নেওয়াই ভাল, বিশেষত যদি কোনও বড় পারফরম্যান্স ওভারহেড ছাড়াই এটি করার উপায় থাকে। একটি অতিমাত্রায় TOPঅপারেটর যুক্ত করে কোনও উত্পন্ন টেবিলে ডেটা অর্ডার করা সম্ভব । উদাহরণ স্বরূপ:

(SELECT TOP (26) CHR FROM FIRST_CHAR ORDER BY CHR)

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

ব্যয়বহুল প্রকারের

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

সমস্যার জটিল অংশটি ছিল সঠিক স্থানগুলিতে ফাঁকা অক্ষরগুলি কীভাবে সন্নিবেশ করা যায় তা নির্ধারণ করা। যেমন আগে উল্লেখ করা হয়েছে CROSS JOINতার ফলে সদৃশ ডেটা হবে। আমরা জানি যে 100000000 তম স্ট্রিংটির দৈর্ঘ্যের ছয়টি অক্ষর থাকবে কারণ:

26 + 26 ^ 2 + 26 ^ 3 + 26 ^ 4 + 26 ^ 5 = 914654 <100000000

কিন্তু

26 + 26 ^ 2 + 26 ^ 3 + 26 ^ 4 + 26 ^ 5 + 26 ^ 6 = 321272406> 100000000

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

WITH FIRST_CHAR (CHR) AS
(
    SELECT 'A'
    UNION ALL SELECT 'B'
    UNION ALL SELECT 'C'
    UNION ALL SELECT 'D'
    UNION ALL SELECT 'E'
    UNION ALL SELECT 'F'
    UNION ALL SELECT 'G'
    UNION ALL SELECT 'H'
    UNION ALL SELECT 'I'
    UNION ALL SELECT 'J'
    UNION ALL SELECT 'K'
    UNION ALL SELECT 'L'
    UNION ALL SELECT 'M'
    UNION ALL SELECT 'N'
    UNION ALL SELECT 'O'
    UNION ALL SELECT 'P'
    UNION ALL SELECT 'Q'
    UNION ALL SELECT 'R'
    UNION ALL SELECT 'S'
    UNION ALL SELECT 'T'
    UNION ALL SELECT 'U'
    UNION ALL SELECT 'V'
    UNION ALL SELECT 'W'
    UNION ALL SELECT 'X'
    UNION ALL SELECT 'Y'
    UNION ALL SELECT 'Z'
)
, ALL_CHAR (CHR, FLAG) AS
(
    SELECT '', 0 CHR
    UNION ALL SELECT 'A', 1
    UNION ALL SELECT 'B', 1
    UNION ALL SELECT 'C', 1
    UNION ALL SELECT 'D', 1
    UNION ALL SELECT 'E', 1
    UNION ALL SELECT 'F', 1
    UNION ALL SELECT 'G', 1
    UNION ALL SELECT 'H', 1
    UNION ALL SELECT 'I', 1
    UNION ALL SELECT 'J', 1
    UNION ALL SELECT 'K', 1
    UNION ALL SELECT 'L', 1
    UNION ALL SELECT 'M', 1
    UNION ALL SELECT 'N', 1
    UNION ALL SELECT 'O', 1
    UNION ALL SELECT 'P', 1
    UNION ALL SELECT 'Q', 1
    UNION ALL SELECT 'R', 1
    UNION ALL SELECT 'S', 1
    UNION ALL SELECT 'T', 1
    UNION ALL SELECT 'U', 1
    UNION ALL SELECT 'V', 1
    UNION ALL SELECT 'W', 1
    UNION ALL SELECT 'X', 1
    UNION ALL SELECT 'Y', 1
    UNION ALL SELECT 'Z', 1
)
SELECT TOP (100000000)
d6.CHR + d5.CHR + d4.CHR + d3.CHR + d2.CHR + d1.CHR
FROM (SELECT TOP (27) FLAG, CHR FROM ALL_CHAR ORDER BY CHR) d6
CROSS JOIN (SELECT TOP (27) FLAG, CHR FROM ALL_CHAR ORDER BY CHR) d5
CROSS JOIN (SELECT TOP (27) FLAG, CHR FROM ALL_CHAR ORDER BY CHR) d4
CROSS JOIN (SELECT TOP (27) FLAG, CHR FROM ALL_CHAR ORDER BY CHR) d3
CROSS JOIN (SELECT TOP (27) FLAG, CHR FROM ALL_CHAR ORDER BY CHR) d2
CROSS JOIN (SELECT TOP (26) CHR FROM FIRST_CHAR ORDER BY CHR) d1
WHERE (d2.FLAG + d3.FLAG + d4.FLAG + d5.FLAG + d6.FLAG) =
    CASE 
    WHEN d6.FLAG = 1 THEN 5
    WHEN d5.FLAG = 1 THEN 4
    WHEN d4.FLAG = 1 THEN 3
    WHEN d3.FLAG = 1 THEN 2
    WHEN d2.FLAG = 1 THEN 1
    ELSE 0 END
OPTION (MAXDOP 1, FORCE ORDER, LOOP JOIN, NO_PERFORMANCE_SPOOL);

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

MAXDOP 1এবং FORCE ORDERনির্দেশ নিশ্চিত, যাতে ক্যোয়ারীতে সংরক্ষিত আছে করতে অপরিহার্য। একটি টীকায়িত আনুমানিক পরিকল্পনাটি কেন তাদের বর্তমান ক্রমে যোগদান করে তা দেখতে সহায়ক হতে পারে:

এনটোটেড আনুমানিক

অনুসন্ধানের পরিকল্পনাগুলি প্রায়শই ডান থেকে বামে পড়ে থাকে তবে সারি অনুরোধগুলি বাম থেকে ডানে ঘটে। আদর্শভাবে, এসকিউএল সার্ভার d1ধ্রুবক স্ক্যান অপারেটর থেকে 100 মিলিয়ন সারি অনুরোধ করবে । আপনি বাম থেকে ডানে সরানোর সময় আমি প্রতিটি অপারেটরের কাছ থেকে কম সারিগুলির অনুরোধ করার প্রত্যাশা করি। আমরা এটি বাস্তব বাস্তবায়ন পরিকল্পনায় দেখতে পাচ্ছি । অতিরিক্ত হিসাবে, নীচে এসকিউএল সেন্ট্রি প্ল্যান এক্সপ্লোরারের একটি স্ক্রিনশট রয়েছে:

অনুসন্ধানকারী

আমরা ডি 1 থেকে হ'ল 100 মিলিয়ন সারি পেয়েছি যা একটি ভাল জিনিস। নোট করুন যে ডি 2 এবং ডি 3 এর মধ্যে সারিগুলির অনুপাত প্রায় 27: 1 (165336 * 27 = 4464072) যা ক্রস জয়েন কীভাবে কাজ করবে সে সম্পর্কে যদি আপনি চিন্তা করেন তবে তা বোধগম্য হয়। ডি 1 এবং ডি 2 এর মধ্যে সারিগুলির অনুপাত 22.4 যা কিছু নষ্ট কাজের প্রতিনিধিত্ব করে। আমি বিশ্বাস করি যে অতিরিক্ত সারিগুলি সদৃশগুলি (স্ট্রিংগুলির মাঝখানে ফাঁকা অক্ষরের কারণে) থেকে এসেছে যা এটিকে নেস্টেড লুপ জোড় অপারেটর দ্বারা ছাঁটাই করে না যা ফিল্টারিং করে।

LOOP JOINকারণ একটি ইঙ্গিতটি টেকনিক্যালি অপ্রয়োজনীয় CROSS JOINকরতে পারেন শুধুমাত্র একটি লুপ হিসাবে প্রয়োগ করা যেতে SQL সার্ভার যোগ। NO_PERFORMANCE_SPOOLঅপ্রয়োজনীয় টেবিল স্পুলিং প্রতিরোধ করা হয়। স্পুল ইঙ্গিত ছাড়াই ক্যোরিটিকে আমার মেশিনে 3 এক্স বেশি সময় লাগবে।

চূড়ান্ত ক্যোয়ারিতে সিপিইউ সময় প্রায় 17 সেকেন্ড এবং সর্বমোট 18 সেকেন্ডের সময় অতিবাহিত হয়। এসএসএমএসের মাধ্যমে ক্যোয়ারী চালানো এবং ফলাফল সেটটি বাতিল করার সময় এটি ছিল। আমি ডেটা তৈরির অন্যান্য পদ্ধতিগুলি দেখতে খুব আগ্রহী।


2

217,180,147,158 (8 টি অক্ষর) পর্যন্ত কোনও নির্দিষ্ট সংখ্যার জন্য স্ট্রিং কোড পাওয়ার জন্য আমার কাছে সমাধান সমাধান হয়েছে। তবে আমি আপনার সময়কে মারতে পারি না:

আমার মেশিনে, এসকিউএল সার্ভার ২০১৪ সহ, আপনার ক্যোয়ারিতে 18 সেকেন্ড সময় লাগে, যখন আমার 3 মি 46 বার লাগে। উভয় কোয়েরিতে অননুমোদিত ট্রেস পতাকা 8690 ব্যবহার করা হয়েছে কারণ 2014 NO_PERFORMANCE_SPOOLইঙ্গিতটি সমর্থন করে না ।

কোডটি এখানে:

/* precompute offsets and powers to simplify final query */
CREATE TABLE #ExponentsLookup (
    offset          BIGINT NOT NULL,
    offset_end      BIGINT NOT NULL,
    position        INTEGER NOT NULL,
    divisor         BIGINT NOT NULL,
    shifts          BIGINT NOT NULL,
    chars           INTEGER NOT NULL,
    PRIMARY KEY(offset, offset_end, position)
);

WITH base_26_multiples AS ( 
    SELECT  number  AS exponent,
            CAST(POWER(26.0, number) AS BIGINT) AS multiple
    FROM    master.dbo.spt_values
    WHERE   [type] = 'P'
            AND number < 8
),
num_offsets AS (
    SELECT  *,
            -- The maximum posible value is 217180147159 - 1
            LEAD(offset, 1, 217180147159) OVER(
                ORDER BY exponent
            ) AS offset_end
    FROM    (
                SELECT  exponent,
                        SUM(multiple) OVER(
                            ORDER BY exponent
                        ) AS offset
                FROM    base_26_multiples
            ) x
)
INSERT INTO #ExponentsLookup(offset, offset_end, position, divisor, shifts, chars)
SELECT  ofst.offset, ofst.offset_end,
        dgt.number AS position,
        CAST(POWER(26.0, dgt.number) AS BIGINT)     AS divisor,
        CAST(POWER(256.0, dgt.number) AS BIGINT)    AS shifts,
        ofst.exponent + 1                           AS chars
FROM    num_offsets ofst
        LEFT JOIN master.dbo.spt_values dgt --> as many rows as resulting chars in string
            ON [type] = 'P'
            AND dgt.number <= ofst.exponent;

/*  Test the cases in table example */
SELECT  /*  1.- Get the base 26 digit and then shift it to align it to 8 bit boundaries
            2.- Sum the resulting values
            3.- Bias the value with a reference that represent the string 'AAAAAAAA'
            4.- Take the required chars */
        ref.[row_number],
        REVERSE(SUBSTRING(REVERSE(CAST(SUM((((ref.[row_number] - ofst.offset) / ofst.divisor) % 26) * ofst.shifts) +
            CAST(CAST('AAAAAAAA' AS BINARY(8)) AS BIGINT) AS BINARY(8))),
            1, MAX(ofst.chars))) AS string
FROM    (
            VALUES(1),(2),(25),(26),(27),(28),(51),(52),(53),(54),
            (18278),(18279),(475253),(475254),(475255),
            (100000000), (CAST(217180147158 AS BIGINT))
        ) ref([row_number])
        LEFT JOIN #ExponentsLookup ofst
            ON ofst.offset <= ref.[row_number]
            AND ofst.offset_end > ref.[row_number]
GROUP BY
        ref.[row_number]
ORDER BY
        ref.[row_number];

/*  Test with huge set  */
WITH numbers AS (
    SELECT  TOP(100000000)
            ROW_NUMBER() OVER(
                ORDER BY x1.number
            ) AS [row_number]
    FROM    master.dbo.spt_values x1
            CROSS JOIN (SELECT number FROM master.dbo.spt_values WHERE [type] = 'P' AND number < 676) x2
            CROSS JOIN (SELECT number FROM master.dbo.spt_values WHERE [type] = 'P' AND number < 676) x3
    WHERE   x1.number < 219
)
SELECT  /*  1.- Get the base 26 digit and then shift it to align it to 8 bit boundaries
            2.- Sum the resulting values
            3.- Bias the value with a reference that represent the string 'AAAAAAAA'
            4.- Take the required chars */
        ref.[row_number],
        REVERSE(SUBSTRING(REVERSE(CAST(SUM((((ref.[row_number] - ofst.offset) / ofst.divisor) % 26) * ofst.shifts) +
            CAST(CAST('AAAAAAAA' AS BINARY(8)) AS BIGINT) AS BINARY(8))),
            1, MAX(ofst.chars))) AS string
FROM    numbers ref
        LEFT JOIN #ExponentsLookup ofst
            ON ofst.offset <= ref.[row_number]
            AND ofst.offset_end > ref.[row_number]
GROUP BY
        ref.[row_number]
ORDER BY
        ref.[row_number]
OPTION (QUERYTRACEON 8690);

এখানে কৌশলটি হ'ল যেখানে বিচ্ছিন্ন অনুমতিগুলি শুরু হয়:

  1. যখন আপনাকে একটি একক চরটি আউটপুট করতে হয়, আপনার 26 ^ 1 ক্রমান্বয় থাকে যা 26 ^ 0 থেকে শুরু হয়।
  2. যখন আপনাকে 2 টি অক্ষর আউটপুট করতে হয় আপনার 26 ^ 0 + 26 ^ 1 থেকে শুরু হওয়া 26 ^ 2 ক্রিয়াকলাপ থাকে
  3. যখন আপনাকে 3 টি অক্ষর আউটপুট করতে হয় আপনার 26 ^ 0 + 26 ^ 1 + 26 ^ 2 থেকে শুরু হওয়া 26 ^ 3 ক্রমবিধি থাকে
  4. n অক্ষরের জন্য পুনরাবৃত্তি

ব্যবহৃত অন্য কৌশলটি হ'ল সমষ্টিটি চেষ্টা করার পরিবর্তে সঠিক মানটি পেতে যোগফল ব্যবহার করা। এটি অর্জনের জন্য আমি কেবল বেস 26 থেকে বেস 256 পর্যন্ত অঙ্কগুলি অফসেট করি এবং প্রতিটি সংখ্যার জন্য 'এ' এর আসকি মান যুক্ত করি। সুতরাং আমরা যে স্ট্রিংটির সন্ধান করছি তার বাইনারি উপস্থাপনা পাই। এর পরে কিছু স্ট্রিং ম্যানিপুলেশনগুলি প্রক্রিয়াটি সম্পূর্ণ করে।


-1

ঠিক আছে, এখানে আমার সর্বশেষ স্ক্রিপ্ট আছে।

কোন লুপ, কোন পুনরাবৃত্তি।

এটি কেবল 6 চরের জন্য কাজ করে

সবচেয়ে বড় ড্রব্যাক এটি 1,00,00,000 এর জন্য প্রায় 22 মিনিট সময় নেয়

এবার আমার স্ক্রিপ্টটি খুব ছোট।

SET NoCount on

declare @z int=26
declare @start int=@z+1 
declare @MaxLimit int=10000000

SELECT TOP (@MaxLimit) IDENTITY(int,1,1) AS N
    INTO NumbersTest1
    FROM     master.dbo.spt_values x1   
   CROSS JOIN (SELECT number FROM master.dbo.spt_values WHERE [type] = 'P' AND number < 500) x2
            CROSS JOIN (SELECT number FROM master.dbo.spt_values WHERE [type] = 'P' AND number < 500) x3
    WHERE   x1.number < 219
ALTER TABLE NumbersTest1 ADD CONSTRAINT PK_NumbersTest1 PRIMARY KEY CLUSTERED (N)


select N, strCol from NumbersTest1
cross apply
(
select 
case when IntCol6>0 then  char((IntCol6%@z)+64) else '' end 
+case when IntCol5=0 then 'Z' else isnull(char(IntCol5+64),'') end 
+case when IntCol4=0 then 'Z' else isnull(char(IntCol4+64),'') end 
+case when IntCol3=0 then 'Z' else isnull(char(IntCol3+64),'') end 
+case when IntCol2=0 then 'Z' else isnull(char(IntCol2+64),'') end 
+case when IntCol1=0 then 'Z' else isnull(char(IntCol1+64),'') end strCol
from
(
select  IntCol1,IntCol2,IntCol3,IntCol4
,case when IntCol5>0 then  IntCol5%@z else null end IntCol5

,case when IntCol5/@z>0 and  IntCol5%@z=0 then  IntCol5/@z-1 
when IntCol5/@z>0 then IntCol5/@z
else null end IntCol6
from
(
select IntCol1,IntCol2,IntCol3
,case when IntCol4>0 then  IntCol4%@z else null end IntCol4

,case when IntCol4/@z>0 and  IntCol4%@z=0 then  IntCol4/@z-1 
when IntCol4/@z>0 then IntCol4/@z
else null end IntCol5
from
(
select IntCol1,IntCol2
,case when IntCol3>0 then  IntCol3%@z else null end IntCol3
,case when IntCol3/@z>0 and  IntCol3%@z=0 then  IntCol3/@z-1 
when IntCol3/@z>0 then IntCol3/@z
else null end IntCol4

from
(
select IntCol1
,case when IntCol2>0 then  IntCol2%@z else null end IntCol2
,case when IntCol2/@z>0 and  IntCol2%@z=0 then  IntCol2/@z-1 
when IntCol2/@z>0 then IntCol2/@z
else null end IntCol3

from
(
select case when N>0 then N%@z else null end IntCol1
,case when N%@z=0 and  (N/@z)>1 then (N/@z)-1 else  (N/@z) end IntCol2 

)Lv2
)Lv3
)Lv4
)Lv5
)LV6

)ca

DROP TABLE NumbersTest1

দেখে মনে হচ্ছে উদ্ভূত টেবিলটি একক গণনা স্কেলারে রূপান্তরিত হয়ে গেছে যা কোডের 400000 বর্ণের বেশি। আমি সন্দেহ করি যে গণনার অনেকগুলি ওভারহেড আছে। আপনি নিম্নলিখিত অনুরূপ কিছু চেষ্টা করতে চাইতে পারেন: dbfiddle.uk/… এর উত্তরের মধ্যে এর উপাদানগুলি সংহত করতে নির্দ্বিধায় অনুভব করুন।
জো ওবিশ 1
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.