-
Notifications
You must be signed in to change notification settings - Fork 0
/
18_XML_indexes.sql
131 lines (110 loc) · 3.45 KB
/
18_XML_indexes.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
USE WideWorldImporters
GO
-- ----------------------------------------
-- Создаем таблицу с XML
-- Сводка по всем заказам по заказчикам
-- ----------------------------------------
DROP TABLE IF EXISTS Sales.OrderSummary
GO
CREATE TABLE Sales.OrderSummary
(
ID INT NOT NULL IDENTITY,
CustomerID INT NOT NULL,
OrderSummary XML
)
GO
INSERT INTO Sales.OrderSummary (CustomerID, OrderSummary)
SELECT
CustomerID,
(SELECT
CustomerName 'OrderHeader/CustomerName',
OrderDate 'OrderHeader/OrderDate',
OrderID 'OrderHeader/OrderID',
(SELECT
LineItems2.StockItemID '@ProductID',
StockItems.StockItemName '@ProductName',
LineItems2.UnitPrice '@Price',
Quantity '@Qty'
FROM Sales.OrderLines LineItems2
INNER JOIN Warehouse.StockItems StockItems ON LineItems2.StockItemID = StockItems.StockItemID
WHERE LineItems2.OrderID = Base.OrderID
FOR XML PATH('Product'), TYPE) 'OrderDetails'
FROM
(
SELECT DISTINCT
Customers.CustomerName,
SalesOrder.OrderDate,
SalesOrder.OrderID
FROM Sales.Orders SalesOrder
INNER JOIN Sales.OrderLines LineItem ON SalesOrder.OrderID = LineItem.OrderID
INNER JOIN Sales.Customers Customers ON Customers.CustomerID = SalesOrder.CustomerID
WHERE customers.CustomerID = OuterCust.CustomerID
) Base
FOR XML PATH('Order'), ROOT ('SalesOrders'), TYPE) AS OrderSummary
FROM Sales.Customers OuterCust
GO
-- Посмотрим, что получилось
SELECT TOP 1 * FROM Sales.OrderSummary
-- Нужен первичный ключ с кластерным индексом
ALTER TABLE Sales.OrderSummary
ADD CONSTRAINT PK_OrderSummary
PRIMARY KEY CLUSTERED(ID)
GO
-- -----------------------
-- Создаем индексы
-- -----------------------
exec sp_spaceused 'Sales.OrderSummary'
-- !!! может выполняться долго
CREATE PRIMARY XML INDEX [PXML_OrderSummary_OrderSummary]
ON Sales.OrderSummary ([OrderSummary])
GO
exec sp_spaceused 'Sales.OrderSummary'
CREATE XML INDEX [SXML_OrderSummary_Path]
ON Sales.OrderSummary (OrderSummary)
USING XML INDEX [PXML_OrderSummary_OrderSummary]
FOR PATH
GO
exec sp_spaceused 'Sales.OrderSummary'
-- Пример селективного индекса в самом конце
-- -----------------------
-- Запросы
-- -----------------------
-- Отображаем статистику
SET STATISTICS TIME ON
GO
-- С path-индексом
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
GO
SELECT *
FROM Sales.OrderSummary
WHERE OrderSummary.exist('/SalesOrders/Order/OrderDetails/Product/.[@ProductID = 223]') = 1
GO
-- Только с primary-индексом
DROP INDEX [SXML_OrderSummary_Path] ON Sales.OrderSummary
GO
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
GO
SELECT *
FROM Sales.OrderSummary
WHERE OrderSummary.exist('/SalesOrders/Order/OrderDetails/Product/.[@ProductID = 223]') = 1
GO
-- Без индексов
DROP INDEX [PXML_OrderSummary_OrderSummary] ON Sales.OrderSummary
GO
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
GO
SELECT *
FROM Sales.OrderSummary
WHERE OrderSummary.exist('/SalesOrders/Order/OrderDetails/Product/.[@ProductID = 223]') = 1
-- SELECTIVE index
CREATE SELECTIVE XML INDEX [SEL_XML_OrderSummary_OrderSummary]
ON Sales.OrderSummary ([OrderSummary])
FOR
(
pathSalesPersonID = '/SalesOrders/Order/OrderDetails/Product'
)
GO
exec sp_spaceused 'Sales.OrderSummary'