আপনি এই কার্যকর করার পরিকল্পনা ব্যাখ্যা করতে পারেন?


20

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

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('t') AND type in (N'U'))
DROP TABLE t
GO

CREATE TABLE t 
(
 c1 int IDENTITY(1,1) NOT NULL 
,c2 int NULL
) 
GO

insert into t
select top 1000000 a from
(select t1.number*2048 + t2.number a, newid() b
from [master]..spt_values t1 
cross join  [master]..spt_values t2
where t1.[type] = 'P' and t2.[type] = 'P') a
order by b
GO

update t set c2 = null
where c2 < 2048 * 2048 / 10
GO


CREATE CLUSTERED INDEX pk ON [t] (c1)
GO

CREATE NONCLUSTERED INDEX i ON t (c2)
GO

এখন, এই ডেটা দেওয়া, আমি নিম্নলিখিত কোয়েরি অনুরোধ:

select * 
from t 
where 
      c2 < 1048576 
   or c2 is null
;

আমার মহান বিস্ময়, ফাঁসি পরিকল্পনা যে এই জিজ্ঞাসার জন্য উত্পন্ন করা হয়েছিল করার জন্য, ছিল এই । (বাহ্যিক লিঙ্কটির জন্য দুঃখিত, এটি এখানে ফিট করা খুব বড়)

এই সমস্ত " কনস্ট্যান্ট স্ক্যান " এবং " কম্পিউট স্কেলারস " এর সাথে কী চলছে তা আমাকে কেউ ব্যাখ্যা করতে পারেন ? কি হচ্ছে?

পরিকল্পনা

  |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1010], [Expr1011], [Expr1012]))
       |--Merge Interval
       |    |--Sort(TOP 2, ORDER BY:([Expr1013] DESC, [Expr1014] ASC, [Expr1010] ASC, [Expr1015] DESC))
       |         |--Compute Scalar(DEFINE:([Expr1013]=((4)&[Expr1012]) = (4) AND NULL = [Expr1010], [Expr1014]=(4)&[Expr1012], [Expr1015]=(16)&[Expr1012]))
       |              |--Concatenation
       |                   |--Compute Scalar(DEFINE:([Expr1005]=NULL, [Expr1006]=NULL, [Expr1004]=(60)))
       |                   |    |--Constant Scan
       |                   |--Compute Scalar(DEFINE:([Expr1008]=NULL, [Expr1009]=(1048576), [Expr1007]=(10)))
       |                        |--Constant Scan
       |--Index Seek(OBJECT:([t].[i]), SEEK:([t].[c2] > [Expr1010] AND [t].[c2] < [Expr1011]) ORDERED FORWARD)

উত্তর:


29

ধ্রুব স্ক্যানগুলি প্রতিটি কলাম ছাড়াই একটি একক ইন মেমরি সারি তৈরি করে। শীর্ষ গণনা স্কেলার 3 কলাম সহ একটি একক সারি আউটপুট দেয়

Expr1005    Expr1006    Expr1004
----------- ----------- -----------
NULL        NULL        60

নীচের কম্পিউট স্কেলারটি 3 টি কলাম সহ একক সারি আউটপুট করে

Expr1008    Expr1009    Expr1007
----------- ----------- -----------
NULL        1048576        10

সংক্ষেপে অপারেটর ইউনিয়নগুলি এই 2 টি সারি এক সাথে করে এবং 3 টি কলাম আউটপুট দেয় তবে সেগুলি এখন নামকরণ করা হয়েছে

Expr1010    Expr1011    Expr1012
----------- ----------- -----------
NULL        NULL        60
NULL        1048576     10

Expr1012কলাম পতাকার গুচ্ছ অভ্যন্তরীণভাবে ব্যবহৃত নির্দিষ্ট সংজ্ঞায়িত করতে সংগ্রহস্থল ইঞ্জিন জন্য বৈশিষ্ট্যাবলী চাইতে

পরের কম্পিউট স্কেলারটি 2 টি সারি আউটপুট করে

Expr1010    Expr1011    Expr1012    Expr1013    Expr1014    Expr1015
----------- ----------- ----------- ----------- ----------- -----------
NULL        NULL        60          True        4           16            
NULL        1048576     10          False       0           0      

শেষ তিনটি কলাম নিম্নলিখিত হিসাবে সংজ্ঞায়িত করা হয়েছে এবং মার্জ ইন্টারভাল অপারেটরের কাছে উপস্থাপনের আগে বাছাইয়ের উদ্দেশ্যে ব্যবহৃত হয়

[Expr1013] = Scalar Operator(((4)&[Expr1012]) = (4) AND NULL = [Expr1010]), 
[Expr1014] = Scalar Operator((4)&[Expr1012]), 
[Expr1015] = Scalar Operator((16)&[Expr1012])

Expr1014এবং Expr1015পতাকাটিতে নির্দিষ্ট বিট রয়েছে কিনা তা পরীক্ষা করুন। Expr1013যদি উভয়ই বিট 4চালু থাকে এবং Expr1010হয় তবে বুুলিয়ান কলামটি সত্য বলে প্রতীয়মান NULL

ক্যোয়ারীতে অন্যান্য তুলনা অপারেটরদের চেষ্টা করে আমি এই ফলাফলগুলি পেয়েছি

+----------+----------+----------+-------------+----+----+---+---+---+---+
| Operator | Expr1010 | Expr1011 | Flags (Dec) |       Flags (Bin)       |
|          |          |          |             | 32 | 16 | 8 | 4 | 2 | 1 |
+----------+----------+----------+-------------+----+----+---+---+---+---+
| >        | 1048576  | NULL     |           6 |  0 |  0 | 0 | 1 | 1 | 0 |
| >=       | 1048576  | NULL     |          22 |  0 |  1 | 0 | 1 | 1 | 0 |
| <=       | NULL     | 1048576  |          42 |  1 |  0 | 1 | 0 | 1 | 0 |
| <        | NULL     | 1048576  |          10 |  0 |  0 | 1 | 0 | 1 | 0 |
| =        | 1048576  | 1048576  |          62 |  1 |  1 | 1 | 1 | 1 | 0 |
| IS NULL  | NULL     | NULL     |          60 |  1 |  1 | 1 | 1 | 0 | 0 |
+----------+----------+----------+-------------+----+----+---+---+---+---+

যা থেকে আমি অনুমান করি যে বিট 4 এর অর্থ "হ্যাঁস অফ রেঞ্জ" (আনবাউন্ডেড হওয়ার বিপরীতে) এবং বিট 16 এর অর্থ হল পরিসরের শুরুটি অন্তর্ভুক্ত।

এই 6 কলামের ফলাফল সেটটি SORTসাজানো অপারেটর থেকে নির্গত হয় Expr1013 DESC, Expr1014 ASC, Expr1010 ASC, Expr1015 DESC। ধরে নেওয়া যাক Trueদ্বারা প্রতিনিধিত্ব করা হয় 1এবং Falseদ্বারা 0পূর্বে প্রতিনিধিত্ব resultset যাতে ইতিমধ্যে।

আমার পূর্ববর্তী অনুমানের উপর ভিত্তি করে এই সাজানোর নেট প্রভাবটি নিম্নলিখিত ক্রমে মার্জ অন্তরালে ব্যাপ্তিগুলি উপস্থাপন করা

 ORDER BY 
          HasStartOfRangeAndItIsNullFirst,
          HasUnboundedStartOfRangeFirst,
          StartOfRange,
          StartOfRangeIsInclusiveFirst

মার্জ অন্তর অপারেটর 2 টি সারি আউটপুট করে

Expr1010    Expr1011    Expr1012
----------- ----------- -----------
NULL        NULL        60
NULL        1048576     10

প্রতিটি সারি নির্গত জন্য একটি পরিসীমা সন্ধান করা হয়

Seek Keys[1]: Start:[dbo].[t].c2 > Scalar Operator([Expr1010]), 
               End: [dbo].[t].c2 < Scalar Operator([Expr1011])

সুতরাং এটি দুটি সিক সম্পাদিত হয় যেমন প্রদর্শিত হবে। একটি দৃশ্যত > NULL AND < NULLএবং এক > NULL AND < 1048576। তবে যে পতাকাগুলি পাস হয়ে গেছে সেগুলি যথাক্রমে এটিকে IS NULLএবং সংশোধন < 1048576করে। আশা করি @ এসকিউলিকিউই এটি পরিষ্কার করতে এবং কোনও ভুলত্রুটি সংশোধন করতে পারবেন!

আপনি যদি কোয়েরিটি কিছুটা পরিবর্তন করেন

select *
from t 
where 
      c2 > 1048576 
   or c2 = 0
;

তারপরে পরিকল্পনাটি একাধিক অনুসন্ধানের পূর্বাভাসের সাথে একটি সূচক সন্ধানের সাথে আরও সহজ দেখায়।

পরিকল্পনাটি দেখায় Seek Keys

Start: c2 >= 0, End: c2 <= 0, 
Start: c2 > 1048576

ওপিতে মামলার জন্য কেন এই সহজ পরিকল্পনাটি ব্যবহার করা যাবে না তার ব্যাখ্যা এসকিউএলকিভি পূর্ববর্তী লিঙ্কযুক্ত ব্লগ পোস্টের মন্তব্যে দিয়েছেন ।

একাধিক পূর্বাভাসীর সাথে একটি সূচক সন্ধান বিভিন্ন ধরণের তুলনা প্রাকটিকেট মিশ্রণ করতে পারে না (উদাহরণস্বরূপ Isএবং Eqওপিতে ক্ষেত্রে)। এটি কেবল পণ্যের বর্তমান সীমাবদ্ধতা (এবং সম্ভবত শেষ ক্যোয়ারিতে সাম্যতা পরীক্ষাটি c2 = 0প্রয়োগ করে প্রয়োগ করা হয়েছে >=এবং <=কেবল খাঁটি সাম্যতার চেয়ে আপনি অনুসন্ধানের জন্য যাচ্ছেন তার চেয়ে বেশি কারণ সম্ভবত c2 = 0 OR c2 = 1048576


আমি পৌলের নিবন্ধটিতে এমন কোনও স্পট দেখতে পাচ্ছি না যা [Expr1012] এর পতাকাগুলির মধ্যে পার্থক্য ব্যাখ্যা করে। 60/10 এখানে যা বোঝায় তা কি আপনি অনুদান করতে পারেন?
মার্ক স্টোর-স্মিথ

@ মার্কস্টোরী-স্মিথ - তিনি বলেছেন 62সমতার তুলনার জন্য। আমার ধারণা অনুমান করা 60উচিত যে > AND < পরিকল্পনায় দেখানো পরিবর্তে আপনি বাস্তবে পাবেন >= AND <=যদি না এটি একটি সুস্পষ্ট IS NULLপতাকা না পাওয়া যায় (?) অথবা সম্ভবত কিছুটা 2অপ্রাসঙ্গিকভাবে কিছু নির্দেশ করে এবং 60তখনও এটি সমতা হয় যখন আমি করি set ansi_nulls offএবং এটিতে পরিবর্তন c2 = nullকরি তখনও স্থির থাকে60
মার্টিন স্মিথ

2
@ মার্টিনস্মিথ 60 সত্যই নুলের সাথে তুলনার জন্য। পরিসীমা সীমানা এক্সপ্রেশন দুটি প্রান্তে 'আনবাউন্ডেড' প্রতিনিধিত্ব করতে NULL ব্যবহার করে। সন্ধান সর্বদা একচেটিয়া থাকে যেমন শুরু করুন:> এক্সপ্রেস এবং সমাপ্তি: <> অন্তর্ভুক্ত না করে এক্সপ্রেশন> = এবং <= ব্যবহার করে। ব্লগের মন্তব্যের জন্য ধন্যবাদ, আমি সকালে উত্তরে একটি উত্তর বা দীর্ঘ মন্তব্য পোস্ট করব (এখনই এটি বিচার করতে দেরী হবে)।
পল হোয়াইট GoFundMonica বলেছেন

@ এসকিউএলকিউ - ধন্যবাদ এটা বোধগম্য. আশা করি এর আগে আমি কিছু হারিয়ে যাওয়া বিট বের করে ফেলব।
মার্টিন স্মিথ

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

13

ধ্রুবক স্ক্যানগুলি এসকিউএল সার্ভারের এমন একটি বালতি তৈরির একটি উপায় যার মধ্যে এটি কার্যকর করার পরিকল্পনার পরে কিছু রাখে something আমি এর আরও বিশদ বিবরণ এখানে পোস্ট করেছি । ধ্রুব স্ক্যানটি কী জন্য তা বুঝতে, আপনাকে আরও পরিকল্পনার দিকে নজর দিতে হবে। এই ক্ষেত্রে, এটি নিরূপণ স্ক্যান দ্বারা নির্মিত স্থান জনবসতি করতে ব্যবহৃত হচ্ছে গণনা স্কেলার অপারেটর।

কম্পিউট স্কেলার অপারেটরগুলি NULL এবং 1045876 মান দিয়ে লোড করা হচ্ছে, তাই তারা তথ্য স্পষ্ট করার জন্য লুপ জোড় দিয়ে স্পষ্টভাবে ব্যবহার করা হবে।

সত্যিই দুর্দান্ত অংশটি হ'ল এই পরিকল্পনাটি তুচ্ছ। এর অর্থ এটি একটি সর্বনিম্ন অপ্টিমাইজেশন প্রক্রিয়া পেরিয়েছে। সমস্ত ক্রিয়াকলাপ মার্জ বিরতি পর্যন্ত নিয়েছে। এটি সূচী সন্ধানের জন্য তুলনামূলক অপারেটরগুলির একটি সর্বনিম্ন সেট তৈরি করতে ব্যবহৃত হয় (তার উপর বিশদ এখানে )।

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

যোগ করুন: শেষ বাক্যটি বন্ধ রয়েছে is দু'জন চাওয়া ছিল। আমি পরিকল্পনাটি ভুলভাবে লিখেছি। বাকি ধারণাগুলি একই এবং লক্ষ্য, সর্বনিম্ন পাসগুলিও একই।

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