คุณสร้างมุมมองด้วย SNAPSHOT_MATERIALIZATION ใน SQL Server 2017 ได้อย่างไร


36

SQL Server 2017 มีขั้นตอนการจัดเก็บใหม่สองสามขั้นตอน:

  • sp_refresh_single_snapshot_view - พารามิเตอร์การป้อนข้อมูลสำหรับ @view_name nvarchar (261), @rgCode int
  • sp_refresh_snapshot_views - พารามิเตอร์ขาเข้าสำหรับ @rgCode int

และรายการใหม่ใน sys.messages:

  • 10149 - ดัชนีที่มี SNAPSHOT_MATERIALIZATION ไม่สามารถสร้างได้ในมุมมอง '%. * ls' เนื่องจากคำจำกัดความการดูประกอบด้วยตารางที่ปรับให้เหมาะสมกับหน่วยความจำ
  • 10642 - SNAPSHOT_MATERIALIZATION ไม่สามารถตั้งค่าสำหรับดัชนี '%. * ls' บน '%. * ls' เนื่องจากใช้กับดัชนีในมุมมองเท่านั้น
  • 10643 - SNAPSHOT_MATERIALIZATION ไม่สามารถตั้งค่าสำหรับ '%. * ls' บน '%. * ls' เพราะใช้กับดัชนีคลัสเตอร์ในมุมมองเท่านั้น
  • 10648 - SNAPSHOT_MATERIALIZATION ไม่สามารถตั้งค่าสำหรับดัชนีที่แบ่งพาร์ติชัน '%. * ls' บน '%. * ls'
  • 10649 - ดัชนี nonclustered '%. * ls' ไม่สามารถสร้างได้ใน '%. * ls' ที่มีดัชนีคลัสเตอร์ '%. * ls' ด้วย SNAPSHOT_MATERIALIZATION
  • 10650 - รีเฟรชมุมมองสแน็ปช็อตต้องมีการเปิดใช้งานการแยกสแน็ปช็อตในฐานข้อมูล
  • 3760 - ไม่สามารถวางดัชนี '%. * ls' ในมุมมอง '%. * ls' ที่มี SNAPSHOT_MATERIALIZATION
  • 4524 - ไม่สามารถเปลี่ยนมุมมอง '%. * ls' ได้เนื่องจากมีสแน็ปช็อตเป็นรูปธรรม
  • 4525 - ไม่สามารถใช้คำแนะนำ '% ls' ในมุมมอง '%. * ls' ที่มีการสร้างสแน็ปช็อตเป็นรูปธรรมก่อนที่จะรีเฟรชมุมมอง

และเหตุการณ์ขยายใหม่:

ภาพรวมมุมมองขยายเหตุการณ์

ดังนั้นเราจะสร้างมุมมองสแน็ปช็อตที่เกิดขึ้นได้อย่างไร (Microsoft ยังไม่ได้บันทึกไว้ชัดเจน) นี่คือส่วนสำคัญกับสิ่งที่ฉันได้ลองมาจนถึงตอนนี้ที่ไม่ได้ทำงาน

คำตอบ:


55

คุณทำไม่ได้ คุณลักษณะนี้ถูกปิดใช้งานในปี 2017 RTM


ที่กล่าวว่าคุณสามารถ ...

ใช้ AdventureWorks:

CREATE VIEW dbo.TH
WITH SCHEMABINDING
AS
SELECT P.ProductID, COUNT_BIG(*) AS cbs
FROM Production.Product AS P
JOIN Production.TransactionHistory AS TH
    ON TH.ProductID = P.ProductID
GROUP BY P.ProductID;
GO
CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.TH (ProductID)
WITH (SNAPSHOT_MATERIALIZATION = ON);

การเปลี่ยนแปลงตารางพื้นฐานจะไม่สะท้อนทันทีในมุมมอง (ตามปกติจะเป็นกรณีที่มี SQL Server) ในทำนองเดียวกันการแก้ไขข้อมูลเทียบกับตารางพื้นฐานไม่จำเป็นต้องรักษามุมมองการจัดทำดัชนีภาพรวม

เพื่อรีเฟรชเนื้อหามุมมองหนึ่งต้องเรียกหนึ่งในกระบวนงานที่เก็บใหม่:

EXECUTE sys.sp_refresh_single_snapshot_view
    @view_name = N'dbo.TH',
    @rgCode = 0; -- don't know what this is for yet

สิ่งนี้สร้างแผนการดำเนินการ:

วางแผน

สิ่งนี้อาจไม่ได้ผลสำหรับคุณเนื่องจากจำเป็นต้องใช้การตั้งค่าสถานะการสืบค้นกลับที่ไม่มีเอกสารหรือคุณต้องทำสิ่งที่น่ารังเกียจโดยเฉพาะอย่างยิ่งที่ฉันทำ: การเขียนไปยังตำแหน่งหน่วยความจำที่ถือธงคุณลักษณะ (ใช้ดีบักเกอร์)

sqllang!g_featureSwitchesLangSvc+0x10fถ้าคุณอยากรู้ธงคุณลักษณะไบต์ที่ sqllang!SpRefreshSingleSnapshotViewมีการตรวจสอบในช่วง

ถ้าคุณต้องการที่จะเล่นและพร้อมที่จะยอมรับผลที่ตามมาจากการแฮ็คในโค้ดของ SQL Server ในขณะที่มันกำลังทำงานอยู่และใช้คุณสมบัติที่ Microsoft ยังไม่คิดว่าพร้อม:

  1. แนบตัวดีบักเกอร์กับกระบวนการ SQL Server 2017 ฉันใช้ WinDbg
  2. ตั้งค่าเบรกพอยต์:

    bp sqllang!SpRefreshSingleSnapshotView
  3. เรียกคืน SQL Server โดยใช้คำสั่ง Go ( g)

  4. สร้างมุมมองด้านบน แต่ไม่ใช่ดัชนีคลัสเตอร์ที่ไม่ซ้ำกัน
  5. เรียกใช้sys.sp_refresh_single_snapshot_viewคำสั่งด้านบน
  6. เมื่อเบรกพอยต์ถูกตีให้ทำตามขั้นตอนจนกว่าคุณจะเห็นบรรทัดโค้ด:

    cmp byte ptr [sqllang!g_featureSwitchesLangSvc+0x10f (00007fff`328dfbcf)],0

    ออฟเซ็ตอาจแตกต่างกันในบิลด์อื่นตัวอย่างเช่นใน 2017 RTM CU3 sqllang!g_featureSwitchesLangSvc+0x114

  7. ที่อยู่หน่วยความจำในวงเล็บอาจแตกต่างกัน ใช้สิ่งที่คุณเห็น

  8. ใช้คำสั่งหน่วยความจำจอแสดงผลเพื่อดูค่าปัจจุบันตามที่อยู่หน่วยความจำที่คุณพบ:

    db 00007fff`328dfbcf L1
  9. สิ่งนี้ควรแสดงศูนย์ซึ่งบ่งชี้ว่าคุณลักษณะนั้นถูกปิดใช้งาน

  10. เปลี่ยนศูนย์เป็นศูนย์โดยใช้คำสั่ง enter values ​​(อีกครั้งด้วยที่อยู่หน่วยความจำของคุณ):

    eb 00007fff`328dfbcf 1
  11. ปิดใช้งานเบรกพอยต์และเรียกใช้ SQL Server ต่อ

  12. เปิดใช้งานคุณสมบัตินี้แล้ว
  13. สร้างดัชนีคลัสเตอร์ที่ไม่ซ้ำกันในมุมมอง
  14. เล่นรอบ ๆ

หมายเหตุSNAPSHOT_MATERIALIZATIONช่วยให้เราสามารถสร้างภาพรวมของข้อกำหนดการสืบค้นที่ไม่สามารถจัดทำดัชนีตามปกติตัวอย่างเช่นการใช้ด้านล่างMAX:

CREATE VIEW dbo.TH2
WITH SCHEMABINDING
AS
SELECT TH.ProductID, MaxTransactionID = MAX(TH.TransactionID)
FROM Production.TransactionHistory AS TH
GROUP BY TH.ProductID;
GO
CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.TH2 (ProductID)
WITH (SNAPSHOT_MATERIALIZATION = ON);

ผล:

คำสั่งสำเร็จแล้ว
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.