আমরা এসকিউএল সার্ভার ২০০৮ আর 2 ব্যবহার করছি, এবং একটি প্রাথমিক আইডি সূচক সহ একটি খুব বড় (100 datetime
এম + সারি) টেবিল এবং একটি অবিচ্ছিন্ন সূচক সহ একটি কলাম রয়েছে। আমরা নির্দিষ্টভাবে একটি সূচকযুক্ত ডেটটাইম কলামে একটি order by
ধারা ব্যবহারের উপর ভিত্তি করে কিছু অতি অস্বাভাবিক ক্লায়েন্ট / সার্ভার আচরণ দেখছি ।
আমি নিম্নলিখিত পোস্টটি পড়েছি: /programming/1716798/sql-server-2008-ordering-by-datetime-is-too-slow তবে ক্লায়েন্ট / সার্ভারের সাথে আরও কিছু চলছে এখানে বর্ণিত শুরু।
আমরা যদি নিম্নলিখিত কোয়েরি চালিত করি (কিছু সামগ্রী রক্ষা করতে সম্পাদিত):
select *
from [big table]
where serial_number = [some number]
order by test_date desc
ক্যোয়ারী প্রতিবার সময় বেরিয়ে যায়। এসকিউএল সার্ভার প্রোফাইলার এ কার্যকর করা ক্যোয়ারী সার্ভারের মতো দেখাচ্ছে:
exec sp_cursorprepexec @p1 output,@p2 output,NULL,N'select * .....
এখন আপনি যদি ক্যোয়ারীটি এখানে পরিবর্তন করেন তবে এটি বলুন:
declare @temp int;
select * from [big table]
where serial_number = [some number]
order by test_date desc
এসকিউএল সার্ভার প্রোফাইলার মৃত্যুদন্ডপ্রাপ্ত ক্যোয়ারীটিকে সার্ভারের মতো দেখায় এবং এটি তাত্ক্ষণিকভাবে কাজ করে:
exec sp_prepexec @p1 output, NULL, N'declare @temp int;select * from .....
প্রকৃতপক্ষে, আপনি অব্যবহৃত ঘোষণাপত্রের পরিবর্তে একটি খালি মন্তব্য ('-;') দিতে পারেন এবং একই ফলাফল পেতে পারেন। সুতরাং প্রথমদিকে আমরা এসপি প্রসেসরটিকে এই সমস্যার মূল কারণ হিসাবে চিহ্নিত করছিলাম তবে আপনি যদি এটি করেন:
select *
from [big table]
where serial_number = [some number]
order by Cast(test_date as smalldatetime) desc
এটি তাত্ক্ষণিকভাবেও কাজ করে (আপনি এটি অন্য কোনও datetime
ধরণের হিসাবে কাস্ট করতে পারেন ), ফলটি মিলি সেকেন্ডে ফেরত দেয়। এবং প্রোফাইলারটি সার্ভারের কাছে অনুরোধটি এইভাবে দেখায়:
exec sp_cursorprepexec @p1 output, @p2 output, NULL, N'select * from .....
যাতে sp_cursorprepexec
সমস্যাটির সম্পূর্ণ কারণ থেকে কিছুটা প্রক্রিয়া বাদ দেয় । এটিকে যুক্ত করুন যে sp_cursorprepexec
যখন কোনও 'অর্ডার বাই' ব্যবহার না করা হয় এবং ফলাফলটি তাত্ক্ষণিকভাবে ফিরে আসে তখন এটিকেও ডাকা হয়।
আমরা এই সমস্যাটি সম্পর্কে বেশ খানিকটা চেষ্টা করেছি এবং আমি অন্যদের কাছ থেকে পোস্ট করা অনুরূপ সমস্যাগুলি দেখতে পাচ্ছি, তবে এটিকে এই স্তরে ভেঙে দেবে না।
তাহলে অন্যরা কি এই আচরণ প্রত্যক্ষ করেছে? আচরণ পরিবর্তন করার জন্য নির্বাচিত স্টেটমেন্টের সামনে অর্থহীন এসকিউএল রাখার চেয়ে কারও কাছে কি আরও ভাল সমাধান আছে? ডেটা সংগ্রহ করার পরে এসকিউএল সার্ভারের অর্ডার করা উচিত, এটি নিশ্চিত মনে হয় যে এটি সার্ভারের একটি বাগ যা দীর্ঘকাল ধরে স্থায়ী। আমরা এই আচরণটি আমাদের অনেক বড় টেবিলের সাথে সামঞ্জস্যপূর্ণ বলে খুঁজে পেয়েছি এবং প্রজননযোগ্য।
সম্পাদনা:
আমারও যুক্ত করা উচিত forceseek
যাতে সমস্যাটি অদৃশ্য হয়ে যায়।
অনুসন্ধানকারীদের সাহায্য করার জন্য আমার যোগ করা উচিত, ওডিবিসি সময়সীমা ত্রুটিটি নিক্ষেপ করা হয়েছে: [মাইক্রোসফ্ট] [ওডিবিসি এসকিউএল সার্ভার ড্রাইভার] অপারেশন বাতিল হয়েছে
যোগ করা হয়েছে 10/12/2012: এখনও মূল কারণটি খুঁজে নিচ্ছেন, (মাইক্রোসফ্টকে দেওয়ার জন্য একটি নমুনা তৈরি করার পাশাপাশি, আমি জমা দেওয়ার পরে এখানে কোনও ফলাফল পোস্ট করব)। আমি একটি ওয়ার্কিং কোয়েরি (একটি অতিরিক্ত মন্তব্য / ঘোষণার বিবৃতি সহ) এবং অ-কার্যকারী ক্যোয়ারির মধ্যে ওডিবিসি ট্রেস ফাইলটিতে খনন করছি। মৌলিক ট্রেস পার্থক্য নীচে পোস্ট করা হয়। এটি এসকিউএলএক্সটেন্ডেডফ্যাচ কলটিতে এসকিউএলবাইন্ডকলকের সমস্ত আলোচনা শেষ হওয়ার পরে ঘটে। কলটি রিটার্ন কোড -1 দিয়ে ব্যর্থ হয় এবং প্যারেন্ট থ্রেড তখন এসকিউএলস্যান্সলে প্রবেশ করে। যেহেতু আমরা নেটিভ ক্লায়েন্ট এবং লেগ্যাসি ওডিবিসি উভয় ড্রাইভারের সাথে এটি উত্পাদন করতে সক্ষম, আমি এখনও সার্ভার সাইডের কিছু সামঞ্জস্যতার ইশারা করছি।
(clip)
MSSQLODBCTester 1664-1718 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)
HSTMT 0x001EEA10
UWORD 16
SWORD 1 <SQL_C_CHAR>
PTR 0x03259030
SQLLEN 51
SQLLEN * 0x0326B820 (0)
MSSQLODBCTester 1664-1718 ENTER SQLExtendedFetch
HSTMT 0x001EEA10
UWORD 1 <SQL_FETCH_NEXT>
SQLLEN 1
SQLULEN * 0x032677C4
UWORD * 0x032679B0
MSSQLODBCTester 1664-1fd0 ENTER SQLCancel
HSTMT 0x001EEA10
MSSQLODBCTester 1664-1718 EXIT SQLExtendedFetch with return code -1 (SQL_ERROR)
HSTMT 0x001EEA10
UWORD 1 <SQL_FETCH_NEXT>
SQLLEN 1
SQLULEN * 0x032677C4
UWORD * 0x032679B0
DIAG [S1008] [Microsoft][ODBC SQL Server Driver]Operation canceled (0)
MSSQLODBCTester 1664-1fd0 EXIT SQLCancel with return code 0 (SQL_SUCCESS)
HSTMT 0x001EEA10
MSSQLODBCTester 1664-1718 ENTER SQLErrorW
HENV 0x001E7238
HDBC 0x001E7B30
HSTMT 0x001EEA10
WCHAR * 0x08BFFC5C
SDWORD * 0x08BFFF08
WCHAR * 0x08BFF85C
SWORD 511
SWORD * 0x08BFFEE6
MSSQLODBCTester 1664-1718 EXIT SQLErrorW with return code 0 (SQL_SUCCESS)
HENV 0x001E7238
HDBC 0x001E7B30
HSTMT 0x001EEA10
WCHAR * 0x08BFFC5C [ 5] "S1008"
SDWORD * 0x08BFFF08 (0)
WCHAR * 0x08BFF85C [ 53] "[Microsoft][ODBC SQL Server Driver]Operation canceled"
SWORD 511
SWORD * 0x08BFFEE6 (53)
MSSQLODBCTester 1664-1718 ENTER SQLErrorW
HENV 0x001E7238
HDBC 0x001E7B30
HSTMT 0x001EEA10
WCHAR * 0x08BFFC5C
SDWORD * 0x08BFFF08
WCHAR * 0x08BFF85C
SWORD 511
SWORD * 0x08BFFEE6
MSSQLODBCTester 1664-1718 EXIT SQLErrorW with return code 100 (SQL_NO_DATA_FOUND)
HENV 0x001E7238
HDBC 0x001E7B30
HSTMT 0x001EEA10
WCHAR * 0x08BFFC5C
SDWORD * 0x08BFFF08
WCHAR * 0x08BFF85C
SWORD 511
SWORD * 0x08BFFEE6
(clip)
একটি মাইক্রোসফ্ট কানেক্ট কেস 10/12/2012 যুক্ত হয়েছে:
আমার এও লক্ষ্য করা উচিত যে আমরা কার্যকারিতা এবং অ-কার্যকারিতা উভয় প্রশ্নের জন্য ক্যোয়ারী পরিকল্পনাগুলি সন্ধান করেছি। এগুলি উভয়ই ফাঁসির গণনার উপর ভিত্তি করে যথাযথভাবে পুনরায় ব্যবহার করা হয়। ক্যাশেড প্ল্যানগুলি ফ্লাশ করা এবং পুনরায় চালানো ক্যোয়ারির সাফল্যকে পরিবর্তন করে না।
sp_executesql
এবং দেখুন কী ঘটে।
select id, test_date from [big table] where serial_number = ..... order by test_date
- আমি কেবল ভাবছি যেSELECT *
এটির দ্বারা আপনার পারফরম্যান্সের নেতিবাচক প্রভাব ফেলবে। আপনার যদি একটি অবিবাহিত সূচক চালু থাকেtest_date
এবং একটি ক্লাস্টারড ইনডেক্স থাকেid
(ধরে নেওয়া যায় এটিই ধরে নেওয়া হয়), এই ক্যোয়ারীটি সেই নন-ক্ল্লাস্টার্ড সূচক দ্বারা আচ্ছাদিত করা উচিত এবং এভাবে খুব দ্রুত ফিরে আসা উচিত