2013-04-18 5 views
1

Следующий запрос занимает много времени, чтобы вернуть результаты. Я попробовал все, что мог придумать, чтобы оптимизировать запрос. В этой структуре хранится около 10000 строк xml, и для возврата результатов требуется около 2,5 МИНУТ. Я установил первичный индекс xml в таблице и вторичный (Property) индекс в таблице. Я установил индексы для перестройки каждые 7 дней.SQl Server Query Performance - Xml Column Shredding

Я ссылаются эти места

Performance Optimizations for the XML Data Type

Guidelines for Using xml Data Type Methods

Xml Index Guidelines

Indexing Xml

Xml Best Practices

Любые советы и предложения были бы благодарны.

Извините Для всего кода, я могу вынуть его, если он не будет принят.

У меня есть таблица:

CREATE TABLE [dbo].[XmlTable](
    [XmlId] [int] IDENTITY(1,1) NOT NULL, 
    [XmlDocument] [xml] NOT NULL, 
CONSTRAINT [PK_XmlTable] PRIMARY KEY CLUSTERED 
(
    [XmlId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 
GO 

С недвижимости Вторичный индекс

SET ARITHABORT ON 
SET CONCAT_NULL_YIELDS_NULL ON 
SET QUOTED_IDENTIFIER ON 
SET ANSI_NULLS ON 
SET ANSI_PADDING ON 
SET ANSI_WARNINGS ON 
SET NUMERIC_ROUNDABORT OFF 

GO 

CREATE XML INDEX [IXML_XmlTable_XmlDocument_Property] ON [dbo].[XmlTable] 
(
    [XmlDocument] 
) 
USING XML INDEX [PXML_XmlTable_XmlDocument] FOR PROPERTY WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
GO 

с первичным индексом

SET ARITHABORT ON 
SET CONCAT_NULL_YIELDS_NULL ON 
SET QUOTED_IDENTIFIER ON 
SET ANSI_NULLS ON 
SET ANSI_PADDING ON 
SET ANSI_WARNINGS ON 
SET NUMERIC_ROUNDABORT OFF 

GO 


CREATE PRIMARY XML INDEX [PXML_XmlTable_XmlDocument] ON [dbo].[XmlTable] 
(
    [XmlDocument] 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
GO 

со структурой, как это:

<dev:Doc xmlns:dev="http://www.w3.org/2001/XMLSchema" SchemaVersion="0.1" Settings="Testing" Title="Ordering"> 
    <dev:Base RevisionNumber="0" Baseid="34433" /> 
    <dev:Rev Time="2013-01-21T15:08:00"> 
    <dev:Person Name="Me" Systemid="54654" /> 
    </dev:Rev> 
    <dev:Functions Id="A1"> 
    <dev:A1 Number="1"> 
     <dev:Codes>D</dev:Codes> 
     <dev:Required>true</dev:Required> 
     <dev:Informational>false</dev:Informational> 
     <dev:Visitors> 
     <dev:Visitor Name="Dev01" Location="STLRF"> 
      <dev:Divisions> 
      <dev:Division Number="1" Name="TFR3" Usage="Monitor"> 
       <dev:Description>Development Fundamentals</dev:Description> 
      </dev:Division> 
      <dev:Division Number="2" Name="DEF32" Usage="Monitor"> 
       <dev:Description>Testing Fundamentals</dev:Description> 
      </dev:Division> 
      <dev:Division Number="3" Name="DEP13" Usage="None"> 
       <dev:Description>Guided Fundamentals</dev:Description> 
      </dev:Division> 
      </dev:Divisions> 
     </dev:Visitor> 
     <dev:Visitor Name="Dev02" Location="STLRF"> 
      <dev:Divisions> 
      <dev:Division Number="1" Name="TFR3" Usage="Monitor"> 
       <dev:Description>Development Fundamentals</dev:Description> 
      </dev:Division> 
      <dev:Division Number="2" Name="DEF32" Usage="Monitor"> 
       <dev:Description>Testing Fundamentals</dev:Description> 
      </dev:Division> 
      <dev:Division Number="3" Name="DEP13" Usage="None"> 
       <dev:Description>Guided Fundamentals</dev:Description> 
      </dev:Division> 
      </dev:Divisions> 
     </dev:Visitor> 
     <dev:Visitor Name="Dev03" Location="FGRTY"> 
      <dev:Divisions> 
      <dev:Division Number="1" Name="TFR3" Usage="Monitor"> 
       <dev:Description>Development Fundamentals</dev:Description> 
      </dev:Division> 
      <dev:Division Number="2" Name="DEF32" Usage="Monitor"> 
       <dev:Description>Testing Fundamentals</dev:Description> 
      </dev:Division> 
      <dev:Division Number="3" Name="DEP13" Usage="None"> 
       <dev:Description>Guided Fundamentals</dev:Description> 
      </dev:Division> 
      </dev:Divisions> 
     </dev:Visitor> 
     </dev:Visitors> 
     <dev:Senders> 
     <dev:Sender Name="FGY(14A)" /> 
     </dev:Senders> 
    </dev:A1> 
    </dev:Functions> 
    <dev:Functions Id="A2"> 
    <dev:A2 Number="1"> 
     <dev:Codes>C</dev:Codes> 
     <dev:Required>true</dev:Required> 
     <dev:Informational>false</dev:Informational> 
     <dev:Remarks>Support</dev:Remarks> 
     <dev:Notes>Ready</dev:Notes> 
     <dev:Visitors> 
     <dev:Visitor Name="GHFF"> 
      <dev:Divisions> 
      <dev:Division Number="0" Name="Trial" Usage="None"> 
       <dev:FromLocation>LOPO</dev:FromLocation> 
       <dev:ToLocation>RDSS</dev:ToLocation> 
       <dev:Description>Rich Filter</dev:Description> 
      </dev:Division> 
      </dev:Divisions> 
     </dev:Visitor> 
     </dev:Visitors> 
     <dev:Senders> 
     <dev:Sender Name="W33R" /> 
     </dev:Senders> 
     <dev:IsReady>true</dev:IsReady> 
     <dev:IsCall>false</dev:IsCall> 
    </dev:A2> 
    <dev:A2 Number="2"> 
     <dev:Codes>A</dev:Codes> 
     <dev:Required>true</dev:Required> 
     <dev:Informational>false</dev:Informational> 
     <dev:Remarks>Loader Ready</dev:Remarks> 
     <dev:Notes>Ready</dev:Notes> 
     <dev:Visitors> 
     <dev:Visitor Name="UDT"> 
      <dev:Divisions> 
      <dev:Division Number="0" Name="Trial" Usage="None"> 
       <dev:FromLocation>TYUJ</dev:FromLocation> 
       <dev:ToLocation>DETF</dev:ToLocation> 
       <dev:Description>Web Enhance</dev:Description> 
      </dev:Division> 
      </dev:Divisions> 
     </dev:Visitor> 
     </dev:Visitors> 
     <dev:Senders> 
     <dev:Sender Name="RJ4" /> 
     </dev:Senders> 
     <dev:IsReady>true</dev:IsReady> 
     <dev:IsCall>false</dev:IsCall> 
    </dev:A2> 
    </dev:Functions> 
</dev:Doc> 

И Запрос:

;WITH XMLNAMESPACES (Default 'http://www.w3.org/2001/XMLSchema') 
SELECT 

a.value('@RevisionNumber[1]', 'INT') AS Number, 
b.value('@Id[1]', 'VARCHAR(10)') AS FunctionID, 
c.value('@Number[1]', 'INT') AS Number, 
d.value('@Name[1]', 'VARCHAR(10)') AS Visitor, 
d.value('@Location[1]', 'VARCHAR(10)') AS Location, 
e.value('@Name[1]', 'NVARCHAR(10)') AS Sender 

From XmlTable as x 

    CROSS APPLY xmlDocument.nodes('Doc/Base') As aa(a) 
    CROSS APPLY xmlDocument.nodes('Doc/Functions') bb(b) 
    CROSS APPLY b.nodes('*') cc(c) 
    CROSS APPLY c.nodes('Visitors/Visitor') dd(d) 
    CROSS APPLY c.nodes('Senders/Sender') ee(e) 

Вот вставка в таблицу и для тестирования я побежал 10000 раз

INSERT INTO XmlTable(XMLDocument) 
SELECT * FROM OPENROWSET(
    BULK 'C:\Users\123\Desktop\Practice.xml', 
    SINGLE_BLOB) AS x; 

Go 10000 

Я был первоначально этот запрос, но это было х3 медленнее, чем выше запрос

;WITH XMLNAMESPACES (default 'http://www.w3.org/2001/XMLSchema') 
SELECT 
    a.value('(Base/@RevisionNumber)[1]', 'INT') AS RevNumber, 
    b.value('@Id[1]', 'VARCHAR(10)') AS FunctionID, 
    c.value('@Number[1]', 'INT') AS Number, 
    d.value('@Name[1]', 'VARCHAR(10)') AS Visitor, 
    d.value('@Location[1]', 'VARCHAR(10)') AS Location, 
    c.value('(Senders/Sender/@Name)[1]', 'VARCHAR(10)') AS Sender 
FROM XmlTable 
CROSS APPLY xmlDocument.nodes('Doc') As aa(a) 
CROSS APPLY a.nodes('Functions') bb(b) 
CROSS APPLY b.nodes('*') cc(c) 
CROSS APPLY c.nodes('Visitors/Visitor') dd(d) 

ответ

2

Прежде всего, похоже, что вы делаете много креста, применительно к измельчению. Вы можете не только продлить от одного поперечного применить общий знаменатель и получить значение как:

a.value('/(element)/(element)[(expression)].value('(@thing)', '(type)'). 

Мое мышление является то, что синтаксис у вас есть это хорошо, но вы создаете иерархию в пять раз по-разному, а затем крест применения это много раз. Я не делал много измельчения xml, но я знаю, что использование нескольких крестов может быть убийцей, поскольку вы принимаете трехмерное значение и по-разному набираете ссылку в пять раз. Вы можете расширить элементы с помощью обозначения «/ (element)».

Я мог ошибаться, и это может быть хорошо. Если вам нужно сделать так много крестов, вы можете сделать их в дампах временного стола, чтобы потенциально ускорить его. Тогда вы также сможете потенциально добавить индексы xml в таблицу temp.EG:

Select a.query('*') 
into #NodeA 
From XmlTable as x 
    CROSS APPLY xmlDocument.nodes('Doc/Base') As aa(a) 

Затем создать индекс XML, если производительность по-прежнему медленно, что уйдет после временных таблиц удаляются. Не уверен в индексах xml, хотя я их не делал. Я знаю, что вы можете отбрасывать и создавать регулярные индексы в временных таблицах, поэтому я бы предположил, что вы можете сделать это с помощью индексов xml.

http://msdn.microsoft.com/en-us/library/bb934097.aspx

EDIT

Имейте в виду, вы также можете смешивать синтаксис «запроса» с синтаксисом «значение», когда измельчающего XML, который является очень полезным для нахождения структуры дерева, а затем заселение результаты , Я делаю это, когда измельчение XML на сервере SSRS отчетов, похожее на это:

Use ReportServer 
GO 

With a as 
       (
       Select 
           c.Name as ReportName 
       ,    cast(sub.ExtensionSettings as xml) XML 
       ,    sub.ModifiedDate as SubscriptionModifiedDate 
       ,    sub.Description 
       ,    sub.LastRunTime 
       from dbo.ReportSchedule rs (nolock) 
           join dbo.Schedule s (nolock) on rs.ScheduleID = s.ScheduleID 
           join dbo.Subscriptions sub (nolock) on rs.SubscriptionID = sub.SubscriptionID 
           join dbo.Catalog c (nolock) on rs.ReportID = c.ItemID 
       ) 
select 
       a.ReportName 
,    a.SubscriptionModifiedDate 
,    a.Description 
,    t.query('/ParameterValues/ParameterValue[* = "Subject"]/Value').value('.', 'varchar(max)') as Subject 
from a 
    cross apply a.XML.nodes('//ParameterValues') as n(t) 
+0

Размещен старший выше запрос, который был больше удара по производительности, я буду переписывать запрос еще раз и посмотреть, как хиты производительности – KeyboardFriendly