sql-server - management - sql server download



এক্সএমএল সার্ভার এক্সএমএল কর্মক্ষমতা অপ্টিমাইজেশন (1)

আমি একটি ডাটাবেসে 34 টি সারি পেয়েছি, প্রতিটি সারিতে এক্সএমএলযুক্ত কলাম রয়েছে - এক্সএমএলটি আসলে এনভিচারার (ম্যাক্স) কলামে একটি এক্সএমএল কলামে নয়।

প্রতিটি সারির জন্য আমি একক ফলাফলসেট হিসাবে এক্সএমএল উপাদানগুলিতে মানগুলি নির্বাচন করছি। অভিনয় বেশ খারাপ। আমি দুটি ভিন্ন প্রশ্নের চেষ্টা করেছি। প্রথমটি কার্যকর করতে প্রায় 22 সেকেন্ড সময় নেয় এবং দ্বিতীয়টি 7 লাগে।

এমনকি 7 সেকেন্ডেও এটি সর্বোত্তমের চেয়ে ধীর গতির, আমি সর্বাধিক 1-2 সেকেন্ডের জন্য আশা করছি।

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

22 সেকেন্ড:

SELECT
    c.ID,
    c.ChannelName,
    [Name] = d.c.value('name[1]','varchar(100)'),
    [Type] = d.c.value('transportName[1]','varchar(100)'),
    [Enabled] = d.c.value('enabled[1]','BIT'),
    [Queued] = d.c.value('properties[1]/destinationConnectorProperties[1]/queueEnabled[1]','varchar(100)'),
    [RetryInterval] = d.c.value('properties[1]/destinationConnectorProperties[1]/retryIntervalMillis[1]','INT'),
    [MaxRetries] = d.c.value('properties[1]/destinationConnectorProperties[1]/retryCount[1]','INT'),
    [RotateQueue] = d.c.value('properties[1]/destinationConnectorProperties[1]/rotate[1]','BIT'),
    [ThreadCount] = d.c.value('properties[1]/destinationConnectorProperties[1]/threadCount[1]','INT'),
    [WaitForPrevious] = d.c.value('waitForPrevious[1]','BIT'),
    [Destination] = COALESCE(
        d.c.value('properties[1]/channelId[1]','varchar(100)'),
        d.c.value('properties[1]/remoteAddress[1]','varchar(100)'),
        d.c.value('properties[1]/wsdlUrl[1]','varchar(1024)')),

    [DestinationPort] = COALESCE(
        d.c.value('properties[1]/remotePort[1]','varchar(100)'),
        d.c.value('properties[1]/port[1]','varchar(1024)')),
    [Service] = d.c.value('properties[1]/service[1]','varchar(1024)'),
    [Operation] = d.c.value('properties[1]/operation[1]','varchar(1024)')
FROM
(
    SELECT
            [ID],
            [ChannelName] = [Name],
            [CFG] = Convert(XML, Channel)
    FROM
            dbo.CHANNEL
) c
CROSS APPLY c.CFG.nodes('/channel/destinationConnectors/connector') d(c)

7 সেকেন্ড, পাঠ্য () ব্যবহারের কারণে। পাঠ্য জিনিস কেন গতি দেয় তা আমার কোনও ধারণা নেই।

SELECT
    c.ID,
    c.ChannelName,
    [Name] = d.c.value('(name/text())[1]','varchar(100)'),
    [Type] = d.c.value('(transportName/text())[1]','varchar(100)'),
    [Enabled] = d.c.value('(enabled/text())[1]','BIT'),
    [Queued] = d.c.value('(properties/destinationConnectorProperties/queueEnabled/text())[1]','varchar(100)'),
    [RetryInterval] = d.c.value('(properties/destinationConnectorProperties/retryIntervalMillis/text())[1]','INT'),
    [MaxRetries] = d.c.value('(properties/destinationConnectorProperties/retryCount/text())[1]','INT'),
    [RotateQueue] = d.c.value('(properties/destinationConnectorProperties/rotate/text())[1]','BIT'),
    [ThreadCount] = d.c.value('(properties/destinationConnectorProperties/threadCount/text())[1]','INT'),
    [WaitForPrevious] = d.c.value('(waitForPrevious/text())[1]','BIT'),
    [Destination] = COALESCE(
        d.c.value('(properties/channelId/text())[1]','varchar(100)'),
        d.c.value('(properties/remoteAddress/text())[1]','varchar(100)'),
        d.c.value('(properties/wsdlUrl/text())[1]','varchar(1024)')),

    [DestinationPort] = COALESCE(
        d.c.value('(properties/remotePort/text())[1]','varchar(100)'),
        d.c.value('(properties/port/text())[1]','varchar(1024)')),
    [Service] = d.c.value('(properties/service/text())[1]','varchar(1024)'),
    [Operation] = d.c.value('(properties/operation/text())[1]','varchar(1024)')
FROM
(
    SELECT
            [ID],
            [ChannelName] = [Name],
            [CFG] = Convert(XML, Channel)
    FROM
            dbo.CHANNEL
) c
CROSS APPLY c.CFG.nodes('/channel/destinationConnectors/connector') d(c)

এই কোয়েরিতে পাঠ্য () পদ্ধতির ব্যবহার করা হয়েছে তবে প্রথমে একটি টেবিল ভেরিয়েবলের এনভিচারার কলামকে এক্সএমএল কলামে রূপান্তর করা হয়েছে। এক সেকেন্ডেরও কম সময়ে কার্যকর করা ...

DECLARE @Xml AS TABLE (
    [ID] NVARCHAR(36) NOT NULL Primary Key,
    [Name] NVARCHAR(100) NOT NULL,
    [CFG] XML NOT NULL
);

INSERT INTO @Xml (ID, Name, CFG)
SELECT
    c.ID,
    c.Name,
    Convert(XML, c.Channel)
FROM
    [dbo].[CHANNEL] c;

SELECT
    c.ID,
    c.ChannelName,
    [Name] = d.c.value('(name/text())[1]','varchar(100)'),
    [Type] = d.c.value('(transportName/text())[1]','varchar(100)'),
    [Enabled] = d.c.value('(enabled/text())[1]','BIT'),
    [Queued] = d.c.value('(properties/destinationConnectorProperties/queueEnabled/text())[1]','varchar(100)'),
    [RetryInterval] = d.c.value('(properties/destinationConnectorProperties/retryIntervalMillis/text())[1]','INT'),
    [MaxRetries] = d.c.value('(properties/destinationConnectorProperties/retryCount/text())[1]','INT'),
    [RotateQueue] = d.c.value('(properties/destinationConnectorProperties/rotate/text())[1]','BIT'),
    [ThreadCount] = d.c.value('(properties/destinationConnectorProperties/threadCount/text())[1]','INT'),
    [WaitForPrevious] = d.c.value('(waitForPrevious/text())[1]','BIT'),
    [Destination] = COALESCE(
        d.c.value('(properties/channelId/text())[1]','varchar(100)'),
        d.c.value('(properties/remoteAddress/text())[1]','varchar(100)'),
        d.c.value('(properties/wsdlUrl/text())[1]','varchar(1024)')),

    [DestinationPort] = COALESCE(
        d.c.value('(properties/remotePort/text())[1]','varchar(100)'),
        d.c.value('(properties/port/text())[1]','varchar(1024)')),
    [Service] = d.c.value('(properties/service/text())[1]','varchar(1024)'),
    [Operation] = d.c.value('(properties/operation/text())[1]','varchar(1024)')
FROM
(
    SELECT
            [ID],
            [ChannelName] = [Name],
            [CFG]
    FROM
            @Xml
) c
CROSS APPLY c.CFG.nodes('/channel/destinationConnectors/connector') d(c)

Answer #1

আমি আপনাকে একটি উত্তর এবং একটি অনুমান দিতে পারি:

প্রথমে আমি আপনার দৃশ্যের ব্যঙ্গ করতে একটি ঘোষিত টেবিল ভেরিয়েবল ব্যবহার করি:

DECLARE @tbl TABLE(s NVARCHAR(MAX));
INSERT INTO @tbl VALUES
(N'<root>
    <SomeElement>This is first text of element1
        <InnerElement>This is text of inner element1</InnerElement>
        This is second text of element1
    </SomeElement>
    <SomeElement>This is first text of element2
        <InnerElement>This is text of inner element2</InnerElement>
        This is second text of element2
    </SomeElement>
</root>')
,(N'<root>
    <SomeElement>This is first text of elementA
        <InnerElement>This is text of inner elementA</InnerElement>
        This is second text of elementA
    </SomeElement>
    <SomeElement>This is first text of elementB
        <InnerElement>This is text of inner elementB</InnerElement>
        This is second text of elementB
    </SomeElement>
</root>');

- এই ক্যোয়ারীটি একটি উপ- বাছাইয়ের বাইরে একটি কাস্ট সহ এক্সএমএল পড়বে। পরিবর্তে আপনি একটি CTE ব্যবহার করতে পারেন, তবে এটি কেবল সিনট্যাকটিকাল চিনি হওয়া উচিত ...

SELECT se.value(N'(.)[1]','nvarchar(max)') SomeElementsContent
      ,se.value(N'(InnerElement)[1]','nvarchar(max)') InnerElementsContent
      ,se.value(N'(./text())[1]','nvarchar(max)') ElementsFirstText
      ,se.value(N'(./text())[2]','nvarchar(max)') ElementsSecondText
FROM (SELECT CAST(s AS XML) FROM @tbl) AS tbl(TheXml)
CROSS APPLY TheXml.nodes(N'/root/SomeElement') AS A(se);

- দ্বিতীয় অংশটি টাইপ করা এক্সএমএল লিখতে এবং সেখান থেকে পড়তে একটি সারণী ব্যবহার করে:

DECLARE @tbl2 TABLE(x XML)
INSERT INTO @tbl2
SELECT CAST(s AS XML) FROM @tbl;

SELECT se.value(N'(.)[1]','nvarchar(max)') SomeElementsContent
      ,se.value(N'(InnerElement)[1]','nvarchar(max)') InnerElementsContent
      ,se.value(N'(./text())[1]','nvarchar(max)') ElementsFirstText
      ,se.value(N'(./text())[2]','nvarchar(max)') ElementsSecondText
FROM @tbl2 t2
CROSS APPLY t2.x.nodes(N'/root/SomeElement') AS A(se);

/text() ছাড়াই কেন দ্রুত?

আপনি যদি আমার উদাহরণটি লক্ষ্য করেন তবে কোনও উপাদানের সামগ্রী হ'ল প্রারম্ভিক নোড থেকে শুরু করে বন্ধ নোড পর্যন্ত সমস্ত কিছু is একটি উপাদানের text() কেবল দুটি উপাদানের মধ্যে ভাসমান পাঠ্য। আপনি উপরের নির্বাচনের ফলাফলগুলিতে এটি দেখতে পারেন। text() আসলে গাছের কাঠামোর একটি পৃথকভাবে সঞ্চিত অংশ (পরবর্তী বিভাগটি পড়ুন)। এটি আনা এক-পদক্ষেপ-পদক্ষেপ । অন্যথায় একটি জটিল কাঠামো খোলার ট্যাগ এবং এর সাথে সম্পর্কিত ক্লোজিং ট্যাগের মধ্যে সবকিছু খুঁজে বের করতে বিশ্লেষণ করতে হবে - এমনকি text() ছাড়া অন্য কিছু না থাকলেও।

আমি কেন যথাযথ ক্ষেত্রে XML সংরক্ষণ করব?

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

প্রাক-কাস্ট করা পদ্ধতির দ্রুততা কেন

এটি অনুমান করা হয় ...
আমার উদাহরণে উভয় পন্থা বেশ সমান এবং প্রায় একই বাস্তবায়ন পরিকল্পনার দিকে নিয়ে যায়।
এসকিউএল সার্ভার আপনি যেমনটি আশা করতে পারেন তেমনভাবে কাজ করে না। এটি কোনও প্রক্রিয়াগত সিস্টেম নয় যেখানে আপনি এটি করার পরে এবং এটি করার পরে এটি করার কথা বলছেন ! । আপনি ইঞ্জিনকে কী চান তা বলুন এবং ইঞ্জিন কীভাবে এটি সর্বোত্তম করবেন তা স্থির করে। এবং ইঞ্জিন এটি দিয়ে বেশ ভাল!
এক্সিকিউশন শুরু হওয়ার আগে ইঞ্জিনটি পদ্ধতির ব্যয় নির্ধারণের চেষ্টা করে। CONVERT (বা CAST ) একটি বরং সস্তা অপারেশন। এটি হতে পারে যে ইঞ্জিনটি আপনার কলগুলির তালিকাটি কাজ করার সিদ্ধান্ত নিয়েছে এবং প্রতিটি একক প্রয়োজনের জন্য বারবার প্রয়োজন হয়েছে, কারণ এটি মনে করে যে এটি কোনও উত্সযুক্ত টেবিলের ব্যয়বহুল সৃষ্টির চেয়ে সস্তা ...






sql-server-2012