বাছাই ক্রম প্রাথমিক কীতে নির্দিষ্ট করা হয়েছে, তবুও বাছাই SELECT এ কার্যকর করা হয়


15

আমি সেন্সরভ্যালুগুলিতে একটি সারণীতে সেন্সর ডেটা সঞ্চয় করছি । টেবিল এবং প্রাথমিক কী নীচে রয়েছে:

CREATE TABLE [dbo].[SensorValues](
  [DeviceId] [int] NOT NULL,
  [SensorId] [int] NOT NULL,
  [SensorValue] [int] NOT NULL,
  [Date] [int] NOT NULL,
CONSTRAINT [PK_SensorValues] PRIMARY KEY CLUSTERED 
(
  [DeviceId] ASC,
  [SensorId] ASC,
  [Date] DESC
) WITH (
    FILLFACTOR=75,
    DATA_COMPRESSION = PAGE,
    PAD_INDEX = OFF,
    STATISTICS_NORECOMPUTE = OFF,
    SORT_IN_TEMPDB = OFF,
    IGNORE_DUP_KEY = OFF,
    ONLINE = OFF,
    ALLOW_ROW_LOCKS = ON,
    ALLOW_PAGE_LOCKS = ON)
  ON [MyPartitioningScheme]([Date])

তবুও, যখন আমি একটি নির্দিষ্ট সময়ের জন্য সেন্সর মানকে বৈধতা নির্বাচন করি তখন এক্সিকিউশন প্ল্যানটি আমাকে বলে যে এটি একটি সাজানোর কাজ করছে। তা কেন?

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

SELECT TOP 1 SensorValue
  FROM SensorValues
  WHERE SensorId = 53
    AND DeviceId = 3819
    AND Date < 1339225010
  ORDER BY Date DESC

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

সম্পাদনা: আমি কি পরিবর্তে এটি করতে পারি?

যেহেতু টেবিল অনুসারে বাছাই করা হয় DeviceId, SensorId, তারিখ এবং আমি একটি কি নির্বাচন শুধুমাত্র একটি নির্দিষ্ট DeviceId এবং এক SensorId , আউটপুট সেট ইতিমধ্যে অনুসারে সাজানো হবে তারিখের নিম্নক্রমে । সুতরাং আমি ভাবছি যদি নিম্নলিখিত প্রশ্নটি সব ক্ষেত্রে একই ফলাফল দেয়?

SELECT TOP 1 SensorValue
  FROM SensorValues
  WHERE SensorId = 53
    AND DeviceId = 3819
    AND Date < 1339225010

নীচের @ ক্যাটক্যাল অনুসারে বাছাই অর্ডার স্টোরেজ অর্ডারের মতো নয়। অর্থাৎ আমরা ধরে নিতে পারি না যে প্রত্যাবর্তিত মানগুলি ইতিমধ্যে একটি সাজানো ক্রমে রয়েছে।

সম্পাদনা: আমি এই ক্রস প্রয়োগের সমাধানটি চেষ্টা করেছি, কোনও ভাগ্য নেই

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

WITH Boundaries(boundary_id)
AS
(
  SELECT boundary_id
  FROM sys.partition_functions pf
  JOIN sys.partition_range_values prf ON pf.function_id = prf.function_id
  WHERE pf.name = 'PF'
  AND prf.value <= 1339225010
  UNION ALL
  SELECT max(boundary_id) + 1
  FROM sys.partition_functions pf
  JOIN sys.partition_range_values prf ON pf.function_id = prf.function_id
  WHERE pf.name = 'PF'
  AND prf.value <= 1339225010
),
Top1(SensorValue)
AS
(
  SELECT TOP 1 d.SensorValue
  FROM Boundaries b
  CROSS APPLY
  (
    SELECT TOP 1 SensorValue
      FROM SensorValues
      WHERE  SensorId = 53
        AND DeviceId = 3819
        AND "Date" < 1339225010
        AND $Partition.PF(Date) = b.boundary_id
        ORDER BY Date DESC
  ) d
  ORDER BY d.Date DESC
)
SELECT SensorValue
FROM Top1

বিকল্প ম্যাক্সডপ 1 সাহায্য করে না। নীচে @ মার্টিন স্মিথ দ্বারা উল্লিখিত হিসাবে মনে হচ্ছে যে পার্টিশনটিই এর কারণ হয়ে
উঠছে

উত্তর:


13

বিভাজনবিহীন টেবিলের জন্য আমি নিম্নলিখিত পরিকল্পনাটি পেয়েছি

পরিকল্পনা 1

একটি সিলেক্ট প্রিকিকেট রয়েছে Seek Keys[1]: Prefix: DeviceId, SensorId = (3819, 53), Start: Date < 1339225010

এর অর্থ যে এসকিউএল সার্ভার প্রথম দুটি কলামে সাম্যতার সন্ধান করতে পারে এবং তারপরে শুরু হয়ে 1339225010অর্ডার করে FORWARD(সূচকটি যেমন সংজ্ঞায়িত হয় [Date] DESC)

TOPচাইতে থেকে পর প্রথম সারিতে নির্গত হয় অপারেটর আরো সারি অনুরোধ করা বন্ধ করবে।

আমি যখন পার্টিশন স্কিম তৈরি করি এবং ফাংশন করি

CREATE PARTITION FUNCTION PF (int)
AS RANGE LEFT FOR VALUES (1000, 1339225009 ,1339225010 , 1339225011);
GO
CREATE PARTITION SCHEME [MyPartitioningScheme]
AS PARTITION PF
ALL TO ([PRIMARY] );

এবং নিম্নলিখিত ডেটা সহ টেবিলটি পপুলেট করুন

INSERT INTO [dbo].[SensorValues]    
/*500 rows matching date and SensorId, DeviceId predicate*/
SELECT TOP (500) 3819,53,1, ROW_NUMBER() OVER (ORDER BY (SELECT 0))           
FROM master..spt_values
UNION ALL
/*700 rows matching date but not SensorId, DeviceId predicate*/
SELECT TOP (700) 3819,52,1, ROW_NUMBER() OVER (ORDER BY (SELECT 0))           
FROM master..spt_values
UNION ALL 
/*1100 rows matching SensorId, DeviceId predicate but not date */
SELECT TOP (1100) 3819,53,1, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) + 1339225011      
FROM master..spt_values

এসকিউএল সার্ভার ২০০৮-এর পরিকল্পনাটি নীচে দেখায়।

পরিকল্পনা 2

সন্ধান থেকে নির্গত সারিগুলির আসল সংখ্যাটি 500। পরিকল্পনা শো পূর্বাভাস সন্ধান করুন

Seek Keys[1]: Start: PtnId1000 <= 2, End: PtnId1000 >= 1, 
Seek Keys[2]: Prefix: DeviceId, SensorId = (3819, 53), Start: Date < 1339225010

এটি বর্ণিত যে এখানে বর্ণিত স্কিপ স্ক্যান পদ্ধতির ব্যবহার করছে

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

এই পরিকল্পনাটি একটি সিরিয়াল পরিকল্পনা এবং তাই আপনার কাছে রয়েছে এমন নির্দিষ্ট ক্যোয়ারির জন্য মনে হয় যে এসকিউএল সার্ভার যদি নিশ্চিত করে যে এটি পার্টিশনগুলি ক্রমানুসারে ক্রমানুসারে প্রক্রিয়া করে dateযে মূল প্ল্যানটি TOPএখনও কাজ করবে এবং এটি প্রথম মিলের সারিটি পরে প্রক্রিয়াজাতকরণ বন্ধ করে দিতে পারে বাকি 499 ম্যাচ চালিয়ে যাওয়া এবং আউটপুট করার চেয়ে পাওয়া গেছে।

বাস্তবে 2005 এর পরিকল্পনাটি দেখে মনে হচ্ছে এটি সেই পদ্ধতিকে গ্রহণ করে না

2005 সালে পরিকল্পনা

আমি নিশ্চিত যদি এটা সোজা এগিয়ে 2008 একই পরিকল্পনা পেতে হয়তো বা এটি একটি প্রয়োজন হবে নই OUTER APPLYউপর sys.partition_range_valuesএটা অনুকরণ।



9

অনেক লোক বিশ্বাস করে যে একটি ক্লাস্টারযুক্ত সূচক আউটপুটটিতে একটি সাজানোর অর্ডারের গ্যারান্টি দেয় । তবে এটি যা করে তা নয়; এটি ডিস্কে স্টোরেজ অর্ডারের গ্যারান্টি দেয় ।

উদাহরণস্বরূপ, এই ব্লগ পোস্টটি এবং এটি দীর্ঘ আলোচনা দেখুন


1
ঠিক আছে, এর আগে ওপি আরও বলেছিল, "আমি ভাবতাম যে আমি যেহেতু তারিখ কলাম অনুসারে সাজানো মান সংরক্ষণ করি তাই বাছাইয়ের ঘটনাটি ঘটবে না [sic]।" সমস্যাটির কমপক্ষে একটি অংশ হ'ল একটি ক্লাস্টারড ইনডেক্সটি কী সম্পর্কে ভুল ধারণা। আমি মনে করি যাইহোক এটি সোজা করা ভাল good
মাইক শেরিল 'ক্যাট রিকল'

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


5

আমি অনুমান করছি যে সমান্তরাল পরিকল্পনার কারণে SORT প্রয়োজন needed আমি এটি কিছু ম্লান এবং দূরবর্তী ব্লগ নিবন্ধের ভিত্তিতে তৈরি করেছি: তবে আমি এটি এমএসডিএন-তে পেয়েছি যা এটিকে ন্যায্যতা দেয় বা না পারে

সুতরাং, MAXDOP 1 দিয়ে চেষ্টা করুন এবং দেখুন কী ঘটে ...

"এক্সচেঞ্জ অপারেটর" এর অধীনে সরল আলাপে @ এসকিউএল কিউইয়ের ব্লগ পোস্টে ইঙ্গিত দেওয়া হয়েছে । এবং "DOP ​​নির্ভরতা" এখানে


যদিও আমি এর dateআগে একটি পার্টিশন ফাংশন স্থাপনে বিরক্ত করিনি। এখন আমার কাছে আছে এবং মনে হচ্ছে পার্টিশন হওয়াই অপরাধী হ'ল 2005 এর এই বিশেষ প্রশ্নের জন্য সম্ভবত আরও ভাল আচরণ করা হচ্ছে।
মার্টিন স্মিথ

1

মূলত আপনি ঠিকই বলেছেন - যেহেতু প্রাথমিক কীটি "ডিভাইসআইড, সেন্সরআইডি, তারিখ" ক্রমে রয়েছে তাই কী-এর ডেটা তারিখ অনুসারে বাছাই করা হয় না, তাই ব্যবহার করা যায় না। যদি আপনার কীটি আলাদাভাবে "তারিখ, ডিভাইসআইডি, সেন্সরআইডি" থাকে, তবে কী-এর ডেটা তারিখ অনুসারে বাছাই করা হত , তাই ব্যবহার করা যেতে পারে ...


আপনার উল্লিখিত পদ্ধতিটি আমি ইতিমধ্যে পরিবর্তন করার চেষ্টা করেছি, তাই দুঃখিত হবেন না। যাইহোক, সমস্ত 3 টি কলামে অ-ক্লাস্টারযুক্ত সূচক তৈরি করার চেষ্টা করবে এবং এটি আমাকে কী দেয় তা দেখুন। (অনুপস্থিত সূচকের অনুসন্ধান অব্যাহত রয়েছে ... ;-))
এম__
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.