এসকিএল সার্ভারকে ইন্ট ভেরিয়েবলের সাথে তুলনা করার আগে গণনা (*) ফলাফলকে ইন্টে রূপান্তর করতে হবে কেন?


11

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

নীচে এই জাতীয় একটি ক্যোয়ারী পরিকল্পনার একটি অংশ রয়েছে যেখানে @ আইডকাউন্টকে একটি ভেরিয়েবল হিসাবে সংজ্ঞায়িত করা হয়েছে।

| --Filter (যেখানে: ([Expr1022] = [@ IdCount]))    
 | - কমপিউট স্কেলার (নির্ধারণ: 
  | - স্ট্রিম সমষ্টি (গ্রুপ দ্বারা: ([মক্ক_ডিবি]। [ডিবিও]। [স্কোপ]]। [স্কোপিআইডি]) নির্ধারণ করুন: ([Expr1028] = গণনা (*)))

উত্তর:


17

আপনি এটি একটি integerভেরিয়েবলের সাথে তুলনা করছেন বিষয়টি অপ্রাসঙ্গিক।

পরিকল্পনা COUNTসবসময় একটি হয়েছে CONVERT_IMPLICIT(int,[ExprNNNN],0))যেখানে ExprNNNNমত প্রকাশের ফলাফলের প্রতিনিধিত্বমূলক জন্য লেবেল COUNT

আমার ধৃষ্টতা সর্বদা হয়েছে যে কোড COUNTঠিক যেমন একই কোড কলিং শেষ পর্যন্ত COUNT_BIGএবং কাস্ট রূপান্তর করা প্রয়োজন bigintনিচে ফিরে ফল int

আসলে COUNT_BIG(*)কোয়েরি পরিকল্পনায় এমনকি আলাদা করা যায় না COUNT(*)। উভয় হিসাবে প্রদর্শিত Scalar Operator(Count(*))

COUNT_BIG(nullable_column)এর থেকে সম্পাদন পরিকল্পনায় আলাদা হয়ে যায় COUNT(nullable_column) তবে পরবর্তীকালে এখনও একটি অন্তর্নিহিত কাস্ট ফিরে আসে int

এই ঘটনাটি কিছু প্রমাণ যে নীচে রয়েছে।

WITH 
E1(N) AS 
(
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
)                                       -- 1*10^1 or 10 rows
, E2(N) AS (SELECT 1 FROM E1 a, E1 b)   -- 1*10^2 or 100 rows
, E4(N) AS (SELECT 1 FROM E2 a, E2 b)   -- 1*10^4 or 10,000 rows
, E8(N) AS (SELECT 1 FROM E4 a, E4 b)   -- 1*10^8 or 100,000,000 rows
, E16(N) AS (SELECT 1 FROM E8 a, E8 b)  -- 1*10^16 or 10,000,000,000,000,000 rows
, T(N) AS (SELECT TOP (2150000000) 
                  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS N FROM E16)
SELECT COUNT(CASE WHEN N < 2150000000 THEN 1 END)
FROM T 
OPTION (MAXDOP 1)

এটি আমার ডেস্কটপে চালাতে প্রায় 7 মিনিট সময় নেয় এবং নিম্নলিখিতটি দেয়

এমএসজি 8115, স্তর 16, রাজ্য 2, লাইন 1
গাণিতিক ওভারফ্লো ত্রুটি অভিব্যক্তিটিকে ডেটা টাইপ ইনটে রূপান্তর করে।
সতর্কতা: নাল মান একটি সামগ্রিক বা অন্যান্য এসইটি অপারেশন দ্বারা নির্মূল করা হয়।

যা ইঙ্গিত করে যে আবশ্যকভাবে COUNTএকটি অতিরিক্ত intপ্রবাহিত হওয়ার পরেও (2147483647 এ) অব্যাহত থাকবে এবং শেষ সারিতে (2150000000) COUNTঅপারেটর দ্বারা প্রক্রিয়াটি NULLফিরে আসার বিষয়ে বার্তা প্রেরণ করে ।

রিটার্নের COUNTসাথে এক্সপ্রেশনকে প্রতিস্থাপনের মাধ্যমে তুলনা করার মাধ্যমেSUM(CASE WHEN N < 2150000000 THEN 1 END)

এমএসজি 8115, স্তর 16, রাজ্য 2, লাইন 1
গাণিতিক ওভারফ্লো ত্রুটি অভিব্যক্তিটিকে ডেটা টাইপ ইনটে রূপান্তর করে।

কোন ANSIসতর্কতা সঙ্গে NULL। যা থেকে আমি উপসংহারে এসেছি যে সমাহারকালে ২,১৫০,০০০,০০০ সারি পৌঁছানোর আগেই এই ক্ষেত্রে ওভারফ্লো হয়েছিল।


@ পোলওহাইট - ধন্যবাদ আমার এক্সএমএলের দিকে নজর দেওয়া উচিত ছিল। আমি ScalarOperatorএসএসএমএস বৈশিষ্ট্য উইন্ডোতে প্রদর্শিত মানটির দিকে তাকিয়ে ছিলাম ।
মার্টিন স্মিথ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.