ฉันมีปัญหา I / O กับตารางขนาดใหญ่
สถิติทั่วไป
ตารางมีลักษณะสำคัญดังต่อไปนี้:
- สภาพแวดล้อม: ฐานข้อมูล Azure SQL (ระดับชั้นเป็น P4 พรีเมียม (500 DTU))
- แถว: 2,135,044,521
- พาร์ติชันที่ใช้ 1,275
- ดัชนีคลัสเตอร์และพาร์ติชัน
แบบ
นี่คือการใช้ตาราง:
CREATE TABLE [data].[DemoUnitData](
[UnitID] [bigint] NOT NULL,
[Timestamp] [datetime] NOT NULL,
[Value1] [decimal](18, 2) NULL,
[Value2] [decimal](18, 2) NULL,
[Value3] [decimal](18, 2) NULL,
CONSTRAINT [PK_DemoUnitData] PRIMARY KEY CLUSTERED
(
[UnitID] ASC,
[Timestamp] ASC
)
)
GO
ALTER TABLE [data].[DemoUnitData] WITH NOCHECK ADD CONSTRAINT [FK_DemoUnitData_Unit] FOREIGN KEY([UnitID])
REFERENCES [model].[Unit] ([ID])
GO
ALTER TABLE [data].[DemoUnitData] CHECK CONSTRAINT [FK_DemoUnitData_Unit]
GO
การแบ่งพาร์ติชันเกี่ยวข้องกับสิ่งนี้:
CREATE PARTITION SCHEME [DailyPartitionSchema] AS PARTITION [DailyPartitionFunction] ALL TO ([PRIMARY])
CREATE PARTITION FUNCTION [DailyPartitionFunction] (datetime) AS RANGE RIGHT
FOR VALUES (N'2017-07-25T00:00:00.000', N'2017-07-26T00:00:00.000', N'2017-07-27T00:00:00.000', ... )
คุณภาพของการบริการ
ฉันคิดว่าดัชนีและสถิติได้รับการดูแลอย่างดีทุกคืนโดยการสร้าง / จัดระเบียบใหม่ / ปรับปรุงใหม่แบบส่วนเพิ่ม
นี่คือสถิติดัชนีปัจจุบันของพาร์ติชันดัชนีที่ใช้งานมากที่สุด:
นี่คือคุณสมบัติสถิติปัจจุบันของพาร์ติชันที่ใช้งานหนักที่สุด:
ปัญหา
ฉันเรียกใช้แบบสอบถามอย่างง่าย ๆ ที่มีความถี่สูงเทียบกับตาราง
SELECT [UnitID]
,[Timestamp]
,[Value1]
,[Value2]
,[Value3]
FROM [data].[DemoUnitData]
WHERE [UnitID] = 8877 AND [Timestamp] >= '2018-03-01' AND [Timestamp] < '2018-03-13'
OPTION (MAXDOP 1)
แผนการดำเนินการมีลักษณะดังนี้: https://www.brentozar.com/pastetheplan/?id=rJvI_4TtG
ปัญหาของฉันคือแบบสอบถามเหล่านี้ผลิตการดำเนินงาน I / O จำนวนมากอย่างมากซึ่งส่งผลให้เกิดปัญหาการPAGEIOLATCH_SH
รอคอย
คำถาม
ฉันได้อ่านแล้วว่าการPAGEIOLATCH_SH
รอนั้นมักจะเกี่ยวข้องกับดัชนีที่ไม่เหมาะสม มีคำแนะนำใดที่คุณมีสำหรับฉันในการลดการทำงานของ I / O หรือไม่? อาจจะโดยการเพิ่มดัชนีที่ดีกว่า
คำตอบ 1 - เกี่ยวข้องกับความคิดเห็นจาก @ S4V1N
แผนการสืบค้นที่โพสต์นั้นมาจากแบบสอบถามที่ฉันดำเนินการใน SSMS หลังจากความคิดเห็นของคุณฉันทำการวิจัยเกี่ยวกับประวัติเซิร์ฟเวอร์ แบบสอบถามแบบสะสมที่เรียกใช้จากบริการมีลักษณะแตกต่างกันเล็กน้อย (เกี่ยวข้องกับ EntityFramework)
(@p__linq__0 bigint,@p__linq__1 datetime2(7),@p__linq__2 datetime2(7))
SELECT 1 AS [C1], [Extent1]
.[Timestamp] AS [Timestamp], [Extent1]
.[Value1] AS [Value1], [Extent1]
.[Value2] AS [Value2], [Extent1]
.[Value3] AS [Value3]
FROM [data].[DemoUnitData] AS [Extent1]
WHERE ([Extent1].[UnitID] = @p__linq__0)
AND ([Extent1].[Timestamp] >= @p__linq__1)
AND ([Extent1].[Timestamp] < @p__linq__2) OPTION (MAXDOP 1)
นอกจากนี้แผนยังดูแตกต่าง:
https://www.brentozar.com/pastetheplan/?id=H1fhALpKG
หรือ
https://www.brentozar.com/pastetheplan/?id=S1DFQvpKz
และเช่นเดียวกับที่คุณเห็นที่นี่ประสิทธิภาพของฐานข้อมูลของเรานั้นแทบจะไม่ได้รับผลกระทบจากข้อความค้นหานี้
คำตอบ 2 - เกี่ยวข้องกับคำตอบจาก @Joe Obbish
สำหรับการทดสอบโซลูชันฉันแทนที่ Entity Framework ด้วย SqlCommand อย่างง่าย ผลที่ได้คือการเพิ่มประสิทธิภาพที่น่าทึ่ง!
แผนแบบสอบถามขณะนี้เหมือนกับใน SSMS และตรรกะอ่านและเขียนปล่อยไป ~ 8 ต่อการดำเนินการ
มันยังอธิบายว่าทำไมฉันถึงได้ลดลงอย่างมากหลังจากที่ฉันเปลี่ยนพาร์ติชั่นช่วงจากรายเดือนเป็นรายวัน การหายไปของการกำจัดพาร์ติชันทำให้พาร์ติชันเพิ่มเติมสแกน