(1)索引
XML字段最大支持2G,如果不建立索引,遍歷數據查詢,性能會很差。
- Primary Index 必須有主鍵列,且為聚集索引。該索引中存放XML數據中Tag、Value和Path等信息
- 輔助Path Index 用於基於Path查詢,即XPath查詢
- 輔助Property Index 用於基於節點的查詢
- 輔助Value Index 用於XML值的查詢
XQuery即查詢XML語言,包括基於XPath、Element和Attribute
語法包括FLOWR
For 遍歷滿足條件節點的內容
Let
Order By
Where
Return
(2)索引查詢
原始數據
CREATE TABLE Orders
(OrderID int IDENTITY(1,1),
Customer VARCHAR(20),
SaleDate Date,
OrderDetail xml)
insert orders values('Tom','2009-09-13','
(OrderID int IDENTITY(1,1),
Customer VARCHAR(20),
SaleDate Date,
OrderDetail xml)
<OrderDetails>
<row>
<Product_ID>2</Product_ID>
<Quantity>200</Quantity>
</row>
<row>
<Product_ID>3</Product_ID>
<Quantity>300</Quantity>
</row>
<row>
<Product_ID>1</Product_ID>
<Quantity>400</Quantity>
</row>
</OrderDetails>
')
- Primary Index
create primary xml index xidx_details on orders(OrderDetail)
顯示錯誤:
表 'orders' 需要具有一個包含的列數小於 16 的聚集主鍵,才能為其創建主 XML 索引。
原因是缺少聚集的主鍵列
alter table orders
add constraint pk_orders_orderid
primary key clustered(orderid)
add constraint pk_orders_orderid
primary key clustered(orderid)
- Path Index
--在primary index基礎上,創建path index
create xml index xidx_details_path on orders(OrderDetail) using xml index xidx_details for path
create xml index xidx_details_path on orders(OrderDetail) using xml index xidx_details for path
select OrderID,OrderDetail.query('//OrderDetails/row') from orders
顯示結果
<row>
<Product_ID>2</Product_ID>
<Quantity>200</Quantity>
</row>
<row>
<Product_ID>3</Product_ID>
<Quantity>300</Quantity>
</row>
<row>
<Product_ID>1</Product_ID>
<Quantity>400</Quantity>
</row>
<Product_ID>2</Product_ID>
<Quantity>200</Quantity>
</row>
<row>
<Product_ID>3</Product_ID>
<Quantity>300</Quantity>
</row>
<row>
<Product_ID>1</Product_ID>
<Quantity>400</Quantity>
</row>
- Property Index
--在primary index基礎上,創建property index
create xml index xidx_details_property on orders(OrderDetail) using xml index xidx_details for property
基於Property Index查詢,按照相對路徑//OrderDetails/row查找相同深度的第二個元素
create xml index xidx_details_property on orders(OrderDetail) using xml index xidx_details for property
select OrderID,OrderDetail.query('//OrderDetails/row[Product_ID][2]') from orders
顯示結果:
<row>
<Product_ID>L02</Product_ID>
<Quantity>300</Quantity>
</row>
<Product_ID>L02</Product_ID>
<Quantity>300</Quantity>
</row>
- Value Index
--在primary index基礎上,創建value index
create xml index xidx_details_value on orders(OrderDetail) using xml index xidx_details for value
create xml index xidx_details_value on orders(OrderDetail) using xml index xidx_details for value
--基於value index查詢,按照相對路徑//OrderDetails/row查找Product_ID="L01"的元素
select OrderID,OrderDetail.query('//OrderDetails/row[Product_ID="L01"]') from orders
select OrderID,OrderDetail.query('//OrderDetails/row[Product_ID="L01"]') from orders
顯示結果:
<row>
<Product_ID>L01</Product_ID>
<Quantity>200</Quantity>
</row>
<Product_ID>L01</Product_ID>
<Quantity>200</Quantity>
</row>
詳細介紹如下:
declare @mydoc xml
set @mydoc='
<ROOT>
<AAA>
<BBB ID="1">二層第一個B</BBB>
<BBB ID="2">二層第二個B</BBB>
<CCC>
<DDD>
<BBB ID="3">四層第一個B</BBB>
</DDD>
<BBB ID="4">三層第一個B</BBB>
<BBB ID="5">三層第二個B</BBB>
</CCC>
<DDD>100</DDD>
<DDD>200</DDD>
</AAA>
<AAA>
<DDD>300</DDD>
<DDD>400</DDD>
</AAA>
</ROOT>
'
--絕對路徑,按照ROOT/AAA/BBB路徑查找
select @mydoc.query('/ROOT/AAA/BBB')
顯示結果
select @mydoc.query('/ROOT/AAA/BBB')
<BBB ID="1">二層第一個B</BBB>
<BBB ID="2">二層第二個B</BBB>
<BBB ID="2">二層第二個B</BBB>
--相對路徑,按照所有BBB路徑查找
select @mydoc.query('//BBB')
select @mydoc.query('//BBB')
顯示結果
<BBB ID="1">二層第一個B</BBB>
<BBB ID="2">二層第二個B</BBB>
<BBB ID="3">四層第一個B</BBB>
<BBB ID="4">三層第一個B</BBB>
<BBB ID="5">三層第二個B</BBB>
<BBB ID="2">二層第二個B</BBB>
<BBB ID="3">四層第一個B</BBB>
<BBB ID="4">三層第一個B</BBB>
<BBB ID="5">三層第二個B</BBB>
--相同深度的第一個BBB
select @mydoc.query('//BBB[1]')
select @mydoc.query('//BBB[1]')
顯示結果
<BBB ID="1">二層第一個B</BBB>
<BBB ID="3">四層第一個B</BBB>
<BBB ID="4">三層第一個B</BBB>
<BBB ID="3">四層第一個B</BBB>
<BBB ID="4">三層第一個B</BBB>
--絕對路徑,按照ROOT/AAA/BBB路徑查找的第一個BBB
select @mydoc.query('/ROOT/AAA/BBB[1]')
顯示結果:
select @mydoc.query('/ROOT/AAA/BBB[1]')
<BBB ID="1">二層第一個B</BBB>
--絕對路徑,按照ROOT/AAA/BBB路徑查找的最后一個BBB
select @mydoc.query('/ROOT/AAA/BBB[last()]')
select @mydoc.query('/ROOT/AAA/BBB[last()]')
顯示結果:
<BBB ID="2">二層第二個B</BBB>
--相對路徑,按照所有BBB路徑查找ID=4的BBB(針對Attribute)
select @mydoc.query('//BBB[@ID="4"]')
select @mydoc.query('//BBB[@ID="4"]')
顯示結果:
<BBB ID="4">三層第一個B</BBB>
--絕對路徑,按照所有BBB路徑查找DDD=300的整棵樹信息(針對Element)
select @mydoc.query('/ROOT/AAA[DDD=300]')
顯示結果:
select @mydoc.query('/ROOT/AAA[DDD=300]')
<AAA>
<DDD>300</DDD>
<DDD>400</DDD>
</AAA>
<DDD>300</DDD>
<DDD>400</DDD>
</AAA>
其中,/表示絕對路徑,/AAA/BBB可以找到,但是路徑不完整,則找不到例如/BBB
//表示相對路徑,會自動補全所有上級路徑,例如//BBB可以找到所有****/BBB路徑