তারিখের কাস্ট করা ব্যস্ততাযুক্ত তবে এটি কী ভাল ধারণা?


47

এসকিউএল সার্ভার ২০০৮-এ তারিখের ডেটাটাইপ যুক্ত হয়েছিল।

এতে একটি datetimeকলাম কাস্ট dateকরা ব্যয়বহুল এবং datetimeকলামে একটি সূচক ব্যবহার করতে পারে ।

select *
from T
where cast(DateTimeCol as date) = '20130101';

অন্য বিকল্পটি আপনার পরিবর্তে একটি ব্যাপ্তি ব্যবহার করা।

select *
from T
where DateTimeCol >= '20130101' and
      DateTimeCol < '20130102'

এই প্রশ্নগুলি কি সমানভাবে ভাল বা অন্যটির তুলনায় একটিকে পছন্দ করা উচিত?


4
ফাঁসির পরিকল্পনা কী বলে?
a_horse_with_no_name

3
where cast(date_column as date) = 'value'সি # এর মতো উপস্থাপিত হলে আমি লিনিক 2 এসকিউএল এসকিউএল উত্পন্ন করার বিষয়টি লক্ষ্য করতে সহায়তা করতে পারি না where obj.date_column.Date == date_variable
GSerg

6
এটি একটি দুর্দান্ত কানেক্ট আইটেম। :)
রব

1
কানেক্ট সাইটটি উইকিপিডিয়ায় সরগেবেলের পাশাপাশি মুছে ফেলা হয়েছে
ইভানজিনহো

উত্তর:


59

আজকের দিনে ingালাইয়ের সরগবিলিটির পিছনের প্রক্রিয়াটিকে ডায়নামিক সিক বলে ।

এসকিউএল সার্ভার GetRangeThroughConvertব্যাপ্তির শুরু এবং শেষ পেতে একটি অভ্যন্তরীণ ফাংশন কল করে।

কিছুটা আশ্চর্যজনকভাবে এটি আপনার আক্ষরিক মানগুলির মতো একই পরিসীমা নয়

প্রতি পৃষ্ঠায় সারি এবং প্রতিদিন 1440 সারি দিয়ে একটি সারণী তৈরি করা হচ্ছে

CREATE TABLE T
  (
     DateTimeCol DATETIME PRIMARY KEY,
     Filler      CHAR(8000) DEFAULT 'X'
  );

WITH Nums(Num)
     AS (SELECT number
         FROM   spt_values
         WHERE  type = 'P'
                AND number BETWEEN 1 AND 1440),
     Dates(Date)
     AS (SELECT {d '2012-12-30'} UNION ALL
         SELECT {d '2012-12-31'} UNION ALL
         SELECT {d '2013-01-01'} UNION ALL
         SELECT {d '2013-01-02'} UNION ALL
         SELECT {d '2013-01-03'})
INSERT INTO T
            (DateTimeCol)
SELECT DISTINCT DATEADD(MINUTE, Num, Date)
FROM   Nums,
       Dates 

তারপরে চলছে

SET STATISTICS IO ON;
SET STATISTICS TIME ON;

SELECT *
FROM   T
WHERE  DateTimeCol >= '20130101'
       AND DateTimeCol < '20130102'

SELECT *
FROM   T
WHERE  CAST(DateTimeCol AS DATE) = '20130101'; 

প্রথম ক্যোয়ারীটি 1443পড়েছে এবং দ্বিতীয়টি 2883তাই এটি একটি অতিরিক্ত অতিরিক্ত দিন পড়ছে তারপরে এটি একটি অবশিষ্টাংশের পূর্বাভাসের বিরুদ্ধে তা ত্যাগ করে।

পরিকল্পনাটি দেখায় যে প্রতীকটি হ'ল

Seek Keys[1]: Start: DateTimeCol > Scalar Operator([Expr1006]), 
               End: DateTimeCol < Scalar Operator([Expr1007])

এর পরিবর্তে >= '20130101' ... < '20130102'এটি পড়ে > '20121231' ... < '20130102'তারপরে সমস্ত 2012-12-31সারি ছিন্ন করে ।

এটির উপর নির্ভর করার আরেকটি অসুবিধা হ'ল কার্ডিনালিটির অনুমানগুলি প্রথাগত রেঞ্জের ক্যোয়ারির মতো সঠিক নাও হতে পারে। এটি আপনার এসকিউএল ফিডেলের একটি সংশোধিত সংস্করণে দেখা যাবে ।

টেবিলের সমস্ত 100 টি সারি এখন প্রাকটিকের সাথে মেলে (একই দিনে তারিখের সময় 1 মিনিট পৃথক করে)।

দ্বিতীয় (পরিসীমা) ক্যোয়ারীটি সঠিকভাবে অনুমান করে যে 100 টি মিলবে এবং একটি ক্লাস্টারড ইনডেক্স স্ক্যান ব্যবহার করবে। CAST( AS DATE)ক্যোয়ারী ভুল অনুমান করেন যে শুধুমাত্র এক সারি ম্যাচ হবে এবং কী লুক-সঙ্গে একটি পরিকল্পনা তৈরি করে।

পরিসংখ্যান সম্পূর্ণ উপেক্ষা করা হয় না। যদি টেবিলের সমস্ত সারি একই থাকে datetimeএবং এটি প্রিডিকেট (যেমন 20130101 00:00:00বা 20130101 01:00:00) এর সাথে মিলে যায় তবে পরিকল্পনাটি একটি আনুমানিক 31.6228 সারি সহ একটি ক্লাস্টারড ইনডেক্স স্ক্যান দেখায়।

100 ^ 0.75 = 31.6228

সুতরাং যে ক্ষেত্রে এটি অনুমান এখানে সূত্র থেকে প্রাপ্ত ।

যদি টেবিলের সমস্ত সারি একই থাকে datetimeএবং এটি প্রাকটিকের সাথে মেলে না (উদাহরণস্বরূপ 20130102 01:00:00) তবে এটি 1 এর আনুমানিক সারি গণনা এবং চেহারাগুলির সাথে পরিকল্পনায় ফিরে আসে।

যে ক্ষেত্রে টেবিলের একাধিক DISTINCTমান রয়েছে তার অনুমানযুক্ত সারিগুলি একই রকম মনে হয় যেন কোয়েরিটি ঠিক খুঁজছিল 20130101 00:00:00

যদি পরিসংখ্যান হিস্টোগ্রামে কোনও পদক্ষেপ থাকে 2013-01-01 00:00:00.000তবে অনুমানের উপর ভিত্তি করে তৈরি করা হবে EQ_ROWS(অর্থাত্ date তারিখে অন্যান্য সময় বিবেচনা করা হবে না)। অন্যথায় যদি কোনও পদক্ষেপ না থাকে তবে দেখে মনে হচ্ছে AVG_RANGE_ROWSএটি আশেপাশের পদক্ষেপগুলি ব্যবহার করে ।

যেমন datetimeঅনেক সিস্টেমে প্রায় 3ms এর নির্ভুলতা রয়েছে সেখানে খুব কম আসল নকল মান থাকবে এবং এই সংখ্যাটি 1 হবে।


1
হাই মার্টিন, আপনি কি TL;DRকয়েকটি বুলেট পয়েন্টের সাথে বিভিন্ন কেস যুক্ত করে একটি অংশ জুড়তে পারবেন সেই ক্ষেত্রে, আজকের অভিনেত্রীটি কি এটি একটি ভাল ধারণা বা না?
টিটি।

6
@TT। আমি মনে করি মূল বিষয়টি এটি একটি ভাল ধারণা নয়। আপনি এমন একটি পদ্ধতি কেন ব্যবহার করতে চান যাতে চিট শীট প্রয়োজন?
অ্যারন বারট্রান্ড

10

আমি জানি যে এটির দীর্ঘকালীন মার্টিনের দুর্দান্ত উত্তর রয়েছে but তবে আমি এসকিউএল সার্ভারের নতুন সংস্করণগুলিতে এখানে আচরণে কিছু পরিবর্তন যুক্ত করতে চেয়েছিলাম। এটি কেবল 2008R2 পর্যন্ত পরীক্ষা করা হয়েছে বলে মনে হয়।

নতুন ইউএসইএইচএনটিগুলির সাহায্যে যা কিছু কার্ডিনালিটি অনুমানের সময় ভ্রমণকে সম্ভব করে তোলে আমরা কখন পরিবর্তন হয়ে যায় তা দেখতে পারি।

এসকিউএল ফিডেলের মতো একই সেটআপ ব্যবহার করা।

CREATE TABLE T ( ID INT IDENTITY PRIMARY KEY, DateTimeCol DATETIME, Filler CHAR(8000) NULL );

CREATE INDEX IX_T_DateTimeCol ON T ( DateTimeCol );


WITH E00(N) AS (SELECT 1 UNION ALL SELECT 1),
     E02(N) AS (SELECT 1 FROM E00 a, E00 b),
     E04(N) AS (SELECT 1 FROM E02 a, E02 b),
     E08(N) AS (SELECT 1 FROM E04 a, E04 b),
     Num(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY E08.N) FROM E08)
INSERT INTO T(DateTimeCol)
SELECT TOP 100 DATEADD(MINUTE, Num.N, '20130101')
FROM Num;

আমরা এর মতো বিভিন্ন স্তর পরীক্ষা করতে পারি:

SELECT *
FROM   T
WHERE  CAST(DateTimeCol AS DATE) = '20130101'
OPTION ( USE HINT ( 'QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_100' ));
GO

SELECT *
FROM   T
WHERE  CAST(DateTimeCol AS DATE) = '20130101'
OPTION ( USE HINT ( 'QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_110' ));
GO 

SELECT *
FROM   T
WHERE  CAST(DateTimeCol AS DATE) = '20130101'
OPTION ( USE HINT ( 'QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_120' ));
GO 

SELECT *
FROM   T
WHERE  CAST(DateTimeCol AS DATE) = '20130101'
OPTION ( USE HINT ( 'QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_130' ));
GO 

SELECT *
FROM   T
WHERE  CAST(DateTimeCol AS DATE) = '20130101'
OPTION ( USE HINT ( 'QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_140' ));
GO 

এই সমস্ত জন্য পরিকল্পনা এখানে উপলব্ধ । কমপ্যাট স্তরগুলি 100 এবং 110 উভয়ই মূল অনুসন্ধানের পরিকল্পনা দেয়, তবে কমপ্যাট স্তর 120 দিয়ে শুরু করে আমরা 100 সারি অনুমানের সাথে একই স্ক্যান পরিকল্পনা পেতে শুরু করি। এটি তুলনামূলক মাত্রা 140 পর্যন্ত সত্য।

পাগল

পাগল

পাগল

>= '20130101', < '20130102'পরিকল্পনাগুলির জন্য কার্ডিনালিটির অনুমান 100 থাকবে, যা প্রত্যাশিত ছিল।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.