যেখানে se মান () `এ ক্লজ ফিল্টার হয় তখন কেন দ্বিতীয় বাছাইকৃত সূচক ব্যবহার করা হয় না?


13

সেটআপ:

create table dbo.T
(
  ID int identity primary key,
  XMLDoc xml not null
);

insert into dbo.T(XMLDoc)
select (
       select N.Number
       for xml path(''), type
       )
from (
     select top(10000) row_number() over(order by (select null)) as Number
     from sys.columns as c1, sys.columns as c2
     ) as N;

প্রতিটি সারির জন্য এক্সএমএল নমুনা:

<Number>314</Number>

ক্যোয়ারির কাজটি হ'ল Tএকটি নির্দিষ্ট মান সহ সারিগুলির সংখ্যা গণনা করা <Number>

এটি করার দুটি সুস্পষ্ট উপায় রয়েছে:

select count(*)
from dbo.T as T
where T.XMLDoc.value('/Number[1]', 'int') = 314;

select count(*)
from dbo.T as T
where T.XMLDoc.exist('/Number[. eq 314]') = 1;

এটি প্রমাণিত করে value()এবং exists()নির্বাচিত এক্সএমএল সূচককে কাজ করতে দুটি পৃথক পথ সংজ্ঞা প্রয়োজন।

create selective xml index SIX_T on dbo.T(XMLDoc) for
(
  pathSQL = '/Number' as sql int singleton,
  pathXQUERY = '/Number' as xquery 'xs:double' singleton
);

sqlসংস্করণ জন্য value()এবং xqueryসংস্করণের জন্য হয় exist()

আপনি ভাবতে পারেন যে এর মতো একটি সূচক আপনাকে একটি ভাল সন্ধানের সাথে একটি পরিকল্পনা দেবে তবে নির্বাচনী এক্সএমএল সূচিগুলি সিস্টেম টেবিলের Tক্লাস্টার কীটির মূল কী হিসাবে প্রাথমিক কী সহ সিস্টেম টেবিল হিসাবে প্রয়োগ করা হবে । উল্লিখিত পাথগুলি সেই সারণীতে বিরল কলাম। আপনি যদি সংজ্ঞায়িত পাথগুলির আসল মানগুলির একটি সূচক চান তবে আপনাকে একটি গৌণ নির্বাচনী সূচী তৈরি করতে হবে, প্রতিটি পাথের অভিব্যক্তির জন্য একটি।

create xml index SIX_T_pathSQL on dbo.T(XMLDoc)
  using xml index SIX_T for (pathSQL);

create xml index SIX_T_pathXQUERY on dbo.T(XMLDoc)
  using xml index SIX_T for (pathXQUERY);

এর জন্য ক্যোয়ারী প্ল্যানটি exist()সেকেন্ডারি এক্সএমএল সূচকে সন্ধানকারী এক্সএমএল সূচকের জন্য সিস্টেম টেবিলের একটি মূল অনুসন্ধান (যা প্রয়োজন তা কেন জানি না) এবং চূড়ান্তভাবে এটি অনুসন্ধানের Tচেষ্টা করে যাতে এটি আছে কিনা তা নিশ্চিত করে সেখানে সারি। শেষ অংশটি প্রয়োজনীয় কারণ সিস্টেম সারণী এবং এর মধ্যে কোনও বিদেশী কী বাধা নেই T

এখানে চিত্র বর্ণনা লিখুন

value()ক্যোয়ারির পরিকল্পনাটি এত সুন্দর নয়। এটি Tবিরল কলাম থেকে মান পেতে অভ্যন্তরীণ টেবিলের অন্বেষণের বিরুদ্ধে নেস্টেড লুপগুলির সাথে একটি ক্লাস্টারড ইনডেক্স স্ক্যান করে এবং পরিশেষে মানটিতে ফিল্টার করে।

এখানে চিত্র বর্ণনা লিখুন

যদি একটি নির্বাচনী সূচক ব্যবহার করা উচিত বা না করা উচিত তবে অপ্টিমাইজেশনের আগে সিদ্ধান্ত নেওয়া হয় তবে যদি কোনও মাধ্যমিক নির্বাচক সূচক ব্যবহার করা উচিত বা না হয় তবে এটি অপ্টিমাইজারের দ্বারা ব্যয় ভিত্তিক সিদ্ধান্ত।

যেখানে ক্লজ ফিল্টার করা হয় তখন কেন সেকেন্ডারি সিলেক্টিক ইনডেক্স ব্যবহার করা হয় না value()?

হালনাগাদ:

প্রশ্নগুলি শব্দার্থগতভাবে পৃথক। যদি আপনি মান সহ একটি সারি যোগ করেন

<Number>313</Number>
<Number>314</Number>` 

exist()সংস্করণ 2 সারি গণনা হবে এবং values()কোয়েরি 1 টি সারি গণনা করবে। singletonনির্দেশিকা এসকিউএল সার্ভার ব্যবহার করে সূচী সংজ্ঞা হিসাবে যেমন এখানে নির্দিষ্ট করা হয়েছে সেগুলি আপনাকে একাধিক <Number>উপাদানগুলির সাথে একটি সারি যুক্ত করা থেকে বিরত করবে ।

এটি তবে আমাদের কেবলমাত্র একটি একক মান পাব তা সংক্ষেপককে গ্যারান্টি দিয়ে values()নির্দিষ্ট করে ফাংশনটি ব্যবহার [1]করতে দেয় না। সেই [1]কারণেই আমাদের value()পরিকল্পনায় একটি শীর্ষ এন বাছাই করা রয়েছে ।

দেখে মনে হচ্ছে আমি এখানে একটি উত্তর বন্ধ করছি ...

উত্তর:


11

singletonসূচকের পাথ প্রকাশের ঘোষণার ফলে আপনি একাধিক <Number>উপাদান যুক্ত করতে পারবেন না তবে value()ফাংশনে এক্সপ্রেশনটির ব্যাখ্যা দেওয়ার সময় এক্সকিউয়ের সংকলক এটিকে বিবেচনা করে না । [1]এসকিউএল সার্ভারকে সুখী করতে আপনাকে নির্দিষ্ট করতে হবে। কোনও স্কিমা দিয়ে টাইপ করা এক্সএমএল ব্যবহার করলে তাও কার্যকর হয় না। এবং এর কারণে এসকিউএল সার্ভার এমন একটি কোয়েরি তৈরি করে যা এমন কিছু ব্যবহার করে যা "প্রয়োগ" প্যাটার্ন বলা যেতে পারে।

XML এর পরিবর্তে নিয়মিত টেবিলগুলি ব্যবহার করা সহজ যা কোয়ারির সুনির্দিষ্ট করে আমরা Tঅভ্যন্তরীণ সারণীর বিরুদ্ধে যাচ্ছি তা সিমুলেট করে না দেওয়া ।

বাস্তব টেবিল হিসাবে অভ্যন্তরীণ টেবিলের জন্য এখানে সেটআপ রয়েছে।

create table dbo.xml_sxi_table
(
  pk1 int not null,
  row_id int,
  path_1_id varbinary(900),
  pathSQL_1_sql_value int,
  pathXQUERY_2_value float
);

go

create clustered index SIX_T on xml_sxi_table(pk1, row_id);
create nonclustered index SIX_pathSQL on xml_sxi_table(pathSQL_1_sql_value) where path_1_id is not null;
create nonclustered index SIX_T_pathXQUERY on xml_sxi_table(pathXQUERY_2_value) where path_1_id is not null;

go

insert into dbo.xml_sxi_table(pk1, row_id, path_1_id, pathSQL_1_sql_value, pathXQUERY_2_value)
select T.ID, 1, T.ID, T.ID, T.ID
from dbo.T;

উভয় সারণী জায়গায় রেখে আপনি exist()কোয়েরির সমতুল্য সম্পাদন করতে পারেন ।

select count(*)
from dbo.T
where exists (
             select *
             from dbo.xml_sxi_table as S
             where S.pk1 = T.ID and
                   S.pathXQUERY_2_value = 314 and
                   S.path_1_id is not null
             );

সমতুল্য value()প্রশ্নের সাথে ভালো দেখাবে।

select count(*)
from dbo.T
where (
      select top(1) S.pathSQL_1_sql_value
      from dbo.xml_sxi_table as S
      where S.pk1 = T.ID and
            S.path_1_id is not null
      order by S.path_1_id
      ) = 314;

top(1)এবং order by S.path_1_idঅভিযুক্ত ব্যক্তি এবং এটি হল [1]Xpath এক্সপ্রেশন দায়ী যে।

আমার মনে হয় না মাইক্রোসফ্টের অভ্যন্তরীণ টেবিলের বর্তমান কাঠামোর সাথে এটি ঠিক করা সম্ভব হয়েছে এমনকি আপনাকে ফাংশনটি [1]থেকে বেরিয়ে যাওয়ার অনুমতি দেওয়া হলেও values()। অপ্টিমাইজারের প্রতি গ্যারান্টি দিতে তারা প্রতিটি পাথের অভিব্যক্তির জন্য একাধিক অভ্যন্তরীণ সারণী তৈরি করতে পারে যে <number>প্রতি সারিতে কেবল একটি উপাদান থাকতে পারে । অপটিমাইজারের জন্য "প্রয়োগের ধরণটি ভেঙে ফেলার জন্য" এটি যথেষ্ট হবে তা নিশ্চিত নয়।

আপনার জন্য যারা এই মজাদার এবং আকর্ষণীয় মনে করেন এবং যেহেতু আপনি এখনও এটি পড়ছেন আপনি সম্ভবত are

অভ্যন্তরীণ সারণীর কাঠামোটি দেখার জন্য কিছু প্রশ্ন।

select T.name, 
       T.internal_type_desc, 
       object_name(T.parent_id) as parent_table_name
from sys.internal_tables as T
where T.parent_id = object_id('T');

select C.name as column_name, 
       C.column_id,
       T.name as type_name,
       C.max_length,
       C.is_sparse,
       C.is_nullable
from sys.columns as C
  inner join sys.types as T
    on C.user_type_id = T.user_type_id
where C.object_id in (
                     select T.object_id 
                     from sys.internal_tables as T 
                     where T.parent_id = object_id('T')
                     )
order by C.column_id;

select I.name as index_name,
       I.type_desc,
       I.is_unique,
       I.filter_definition,
       IC.key_ordinal,
       C.name as column_name, 
       C.column_id,
       T.name as type_name,
       C.max_length,
       I.is_unique,
       I.is_unique_constraint
from sys.indexes as I
  inner join sys.index_columns as IC
    on I.object_id = IC.object_id and
       I.index_id = IC.index_id
  inner join sys.columns as C
    on IC.column_id = C.column_id and
       IC.object_id = C.object_id
  inner join sys.types as T
    on C.user_type_id = T.user_type_id
where I.object_id in (
                     select T.object_id 
                     from sys.internal_tables as T 
                     where T.parent_id = object_id('T')
                     );
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.