Lý lịch
Tôi đang cố gắng thiết lập trình tự "lượt truy cập", trong đó nếu một động vật được phát hiện tại cùng một địa điểm ( General_Location
) thì nó được tính là một lần truy cập duy nhất, nhưng nếu nó đi đến nơi khác và sau đó quay lại, đó là chuyến thăm bổ sung đến cùng địa điểm. Vì vậy, nếu động vật được phát hiện theo Location
trình tự
A1, A2, A3, A3, A3, A1, B2, D4, A2
, ví dụ: tất cả các vị trí A (n) thuộc về General_Location
"A", thì điều này sẽ có 6 lần phát hiện đầu tiên là truy cập 1 (@A), tiếp theo là truy cập 2 (@B), tiếp theo là truy cập 3 (@D), tiếp theo là truy cập 4 (trở lại @A).
Vì LAG
và LEAD
không có sẵn trong SQL Server 2008R2 (cũng không có UNBOUNDED PRECEDING
trong PARTITION
mệnh đề ing), tôi đang thử một cách giải quyết như được mô tả trong mục nhập blog của Cơ quan SQL này .
Tôi đang gặp vấn đề về bộ nhớ (không đề cập đến thời gian tính toán) với các điều sau:
WITH s AS (
SELECT
RANK() OVER (PARTITION BY det.Technology, det.XmitID ORDER BY DetectDate ASC, ReceiverID ASC) as DetID,
COALESCE(TA.AnimalID, det.Technology+'-'+cast(da.XmitID AS nvarchar), 'BSVALUE999') as AnimalID,
det.Technology, det.XmitID, DetectDate, det.location as Location, RL.General_Location as GLocation, ReceiverID
FROM
Detections_with_Location as det JOIN
Receiver_Locations as RL
ON det.Location=RL.Location LEFT OUTER JOIN
Tagged_Animal as TA
ON det.AnimalID=TA.AnimalID
)
INSERT INTO ##ttOrder_det (AnimalID, Technology, XmitID, DD, Location, GLocation, ReceiverID, DetID, PrevDD, BinInc)
SELECT
s1.AnimalID, --was a coalesce
s1.Technology, s1.XmitID, s1.DetectDate, s1.Location, s1.GLocation, s1.ReceiverID,
s1.DetID,
sLAG.DetectDate,
CASE WHEN sLAG.DetectDate IS NULL
THEN 1
ELSE CASE WHEN sLAG.GLocation = s1.GLocation
THEN 0
ELSE 1
END
END AS BinInc
FROM s as s1
LEFT OUTER JOIN s AS sLAG ON
s1.DetID = sLAG.DetID + 1 AND
s1.AnimalID= sLAG.AnimalID --and s.Technology=sLAG.Technology and s.XmitID=sLAG.XmitID;
Như nhiều người dùng khác nhau (@MartinSmith, @Frisbee) đã đề cập hoặc ám chỉ, việc sử dụng AnimalID
không phải là khóa chính hoàn chỉnh của Tagged_Animal
, cũng không được xác định trong một ràng buộc UNIQUE. Tuy nhiên, số lượng hàng trong bảng A.AnimalID=B.AnimalID AND A.TagSN<B.TagSN
là (hiện tại) bằng không. Để làm cho truy vấn này trở nên mạnh mẽ, tôi sẽ phải thực thi tính duy nhất đó (hoặc chỉ cần thả TagSN khỏi PK).
Định nghĩa bảng và chỉ mục
## ttOrder_det (bảng tạm thời)
Các chỉ mục hiện được tạo trước khi điền vào bảng; Tôi kiểm tra trải qua nơi tôi chuyển các NONCLUSTERED
phi UNIQUE
tạo chỉ mục cho một vị trí sau khi bảng tạm thời được làm đầy.
CREATE TABLE ##ttOrder_det (
AnimalID nvarchar(50) not null,
Technology varchar(25) not null,
XmitID int not null,
DD DateTime not null,
[Location] [nvarchar](255) NULL,
[GLocation] nvarchar(255) NULL,
PrevDD DateTime NULL,
ReceiverID int not null,
DetID int NOT NULL,
BinInc int NULL,
BinNum int NULL,
CONSTRAINT [PK_ttRDA] PRIMARY KEY CLUSTERED
([AnimalID] ASC, [DD] ASC, ReceiverID ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY];
GO
CREATE NONCLUSTERED INDEX NIX_F on ##ttOrder_det (AnimalID ASC);
CREATE NONCLUSTERED INDEX NIX_VTC ON ##ttOrder_det (ReceiverID ASC, AnimalID ASC);
CREATE NONCLUSTERED INDEX NIX_TCD ON ##ttOrder_det (AnimalID ASC, DD ASC);
CREATE NONCLUSTERED INDEX NIX_R ON ##ttOrder_det (DetID ASC);
CREATE NONCLUSTERED INDEX NIX_A ON ##ttOrder_det (GLocation ASC);
CREATE NONCLUSTERED INDEX NIX_DD ON ##ttOrder_det (DD, PrevDD);
CREATE UNIQUE INDEX UX_CTR ON ##ttOrder_det (AnimalID ASC, DetID ASC);
CREATE NONCLUSTERED INDEX NIX_Bi ON ##ttOrder_det (BinInc ASC);
CREATE NONCLUSTERED INDEX NIX_CT ON ##ttOrder_det (XmitID ASC, Technology ASC);
Tagged_Animal
CREATE TABLE [dbo].[Tagged_Animal](
[DateTagged] [datetime] NULL,
[AnimalID] [nvarchar](50) NOT NULL,
[TagSN] [nvarchar](50) NOT NULL,
[XmitID] [int] NULL,
[Technology] [varchar](25) NULL,
[Animal_SubType] [nvarchar](50) NULL,
[Species] [nvarchar](30) NULL,
[StudyID] [nvarchar](50) NULL,
[Weight] [float] NULL,
[Length] [int] NULL,
[Length_Type] [nvarchar](50) NULL,
[Date_Released] [datetime] NULL,
[Release_Location] [nvarchar](50) NULL,
[Lat] [float] NULL,
[Lon] [float] NULL,
[Course_Dist_km] [float] NULL,
[Sex] [nvarchar](255) NULL,
[Life_Stage] [nvarchar](255) NULL,
[Marking_Method] [nvarchar](255) NULL,
[Tag_Type] [varchar](30) NULL,
[Notes] [nvarchar](255) NULL,
CONSTRAINT [PK_tbl_Tagged_Animal] PRIMARY KEY CLUSTERED
(
[AnimalID] ASC,
[TagSN] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [I_TF_TagCode] ON [dbo].[Tagged_Animal]
(
[XmitID] ASC,
[Technology] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
Phát hiện_with_Location
CREATE TABLE [dbo].[Detections_with_Location](
[AnimalID] [nvarchar](50) NOT NULL,
[XmitID] [int] NOT NULL,
[Technology] [varchar](25) NOT NULL,
[DetectDate] [datetime] NOT NULL,
[ReceiverID] [int] NOT NULL,
[Data] [float] NULL,
[Units] [varchar](50) NULL,
[Location] [nvarchar](255) NULL,
[StartD] [datetime] NULL,
[StopD] [datetime] NULL,
[fname] [nvarchar](255) NULL,
[notes] [nvarchar](max) NULL,
CONSTRAINT [PK_dlwk] PRIMARY KEY CLUSTERED
(
[ReceiverID] ASC,
[Technology] ASC,
[XmitID] ASC,
[DetectDate] ASC,
[AnimalID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [NIX_VTC] ON [dbo].[Detections_with_Location]
(
[ReceiverID] ASC,
[AnimalID] ASC,
[XmitID] ASC,
[Technology] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [NIX_TCpi] ON [dbo].[Detections_with_Location]
(
[XmitID] ASC,
[Technology] ASC
)
INCLUDE ( [DetectDate],
[ReceiverID],
[Data],
[Units],
[Location]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [NIX_TCD] ON [dbo].[Detections_with_Location]
(
[AnimalID] ASC,
[XmitID] ASC,
[Technology] ASC,
[DetectDate] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [NIX_F] ON [dbo].[Detections_with_Location]
(
[AnimalID] ASC
)
INCLUDE ( [XmitID],
[Technology],
[DetectDate],
[ReceiverID],
[Data],
[Units],
[Location]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [NIX_DSS] ON [dbo].[Detections_with_Location]
(
[ReceiverID] ASC,
[Location] ASC,
[StartD] ASC,
[StopD] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
Nhận_Locations
CREATE TABLE [dbo].[Receiver_Locations](
[Region] [nvarchar](50) NULL,
[Location_Long] [nvarchar](50) NULL,
[Location] [nvarchar](50) NOT NULL,
[Lat] [float] NULL,
[Lon] [float] NULL,
[Altitude] [float] NULL,
[Elevation] [float] NULL,
[RiverKm] [float] NULL,
[LocationType] [nvarchar](50) NULL,
[General_Location] [nvarchar](50) NULL,
[Nearest_Access] [nvarchar](50) NULL,
[Responsible_Agent] [nvarchar](50) NULL,
[Agent_Phone] [nvarchar](255) NULL,
[Agent_Email] [nvarchar](255) NULL,
CONSTRAINT [PK_tbl_Receiver_Locations] PRIMARY KEY CLUSTERED
(
[Location] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Kích thước bảng
Tagged_Animals: 10 nghìn Detective_with_Location: 46+
triệu mục Nhận_L_Lations
: 800
Nhận được lỗi cụ thể
Không thể phân bổ không gian cho đối tượng 'dbo.SORT lưu trữ chạy tạm thời: 140737631617024' trong cơ sở dữ liệu 'tempdb' vì nhóm tệp 'PRIMARY' đã đầy. Tạo không gian đĩa bằng cách xóa các tệp không cần thiết, thả các đối tượng trong nhóm fileg, thêm các tệp bổ sung vào filegroup hoặc cài đặt tự động bật cho các tệp hiện có trong filegroup.
Nhật ký giao dịch cho cơ sở dữ liệu 'tempdb' đã đầy. Để tìm hiểu lý do tại sao không gian trong nhật ký không thể được sử dụng lại, hãy xem cột log numuse_wait_desc trong sys.database (tempdb ACTIVE_TRANSACTION)
Đã xảy ra lỗi trong khi thực hiện lô. Thông báo lỗi là: Ngoại lệ của loại 'System.OutOfMemoryException' đã bị ném - (nếu thực hiện
s
dưới dạng chọn trực tiếp sau khoảng 33 triệu bản ghi).
(Ước tính) Kế hoạch thực hiện Tóm tắt mã ban đầu
INSERT
chi phí 0%
SEQUENCE
chi phí 0% nhưng rút ra từ 9 bước phụ khác nhau. Các bước phụ (với chi phí điển hình) là một Index Insert
(2%), tiếp theo là Sort
(8%), tiếp theo là Table Spool
(2%). NIX_A
có chi phí 9% cho Index Insert
và NIX_TCD
cũng không NIX_F
có Sort
bước nào; Các Table Spool
cho NIX_F
là miễn phí.
Các Clustered Index Insert
chi phí là 10%.
Ngoài ra còn có Sort
chi phí 2% và Parallelism
chi phí 1% cho phân phối luồng.
Đối với các SEQUENCE
chi phí, có vẻ như để thêm vào 95%, với các bước khác trị giá 13%, vì vậy rõ ràng là có một số làm tròn "lỗi" ở đâu đó, có khả năng chủ yếu trong 14% Index Insert
- Sort
- Table Spool
chuỗi.
Ghi chú / Tham khảo
Triển khai LAG / LEAD dựa trên mục nhập blog của Cơ quan SQL
Xem thêm Chủ đề Stackexchange này
Những câu hỏi của tôi
Bất kỳ đề xuất để cải thiện?
Tôi có thể phân vùng khi tôi tham gia các bản sao của
s
?Mọi thứ sẽ được cải thiện nếu tôi lập
s
thành một bảng tạm thời kín đáo và lập chỉ mục một cách thích hợp?Sẽ hiệu quả hơn khi tạo các
UNIQUE
chỉ mục trong bảng tạm thời sau khi tất cả các thao tác chèn được thực hiện? Tôi giả định rằng các chỉ sốUNIQUE
(và do đóPRIMARY KEY
) phải được tạo từ trước để ngăn chặn các vi phạm ràng buộc chính.
Để trả lời một trong những câu hỏi của riêng tôi
- Vâng, vâng, nó sẽ. Sau khi tối ưu hóa hơn nữa
- 21 phút để điền vào bảng tạm thời với dữ liệu
- 1 phút để lập chỉ mục
Quá trình này trước đây đã diễn ra ít nhất 1,5 giờ, bị lỗi và không tạo ra bảng kết quả. Trước khi tôi bắt đầu loay hoay với logic của truy vấn, thực sự sẽ mất hơn 4 giờ trước khi xảy ra lỗi.
Thông số kỹ thuật của máy chủ:
Bộ xử lý: Xeon E3-1240 V2 @ 3,4 GHz (4 lõi / 8 luồng)
Bộ nhớ: 16 GB
Tệp phân trang: 16 GB trên ổ SSD 111 GB (miễn phí 52 GB)
+ cơ sở dữ liệu của tôi trên ổ SSD 223 GB (miễn phí 119 GB)
Tình trạng hiện tại
Xem giải pháp / câu trả lời được đăng của tôi.
cast(det.XmitID AS nvarchar(10)), N'BSVALUE999'
<- hãy nhớ rằng nvarchar không có chiều dài và N
kết quả là chuyển đổi ngầm định. Chỉ là một điều nhỏ cần lưu ý. Bạn có thể sử dụng pastebin để đăng một số mã và liên kết nó ở đây.
RANK() OVER (PARTITION BY det.Technology, det.XmitID ORDER BY DetectDate ASC, ReceiverID ASC) as DetID
nhưng sau đó tự tham gia vào s1.DetID = sLAG.DetID + 1 AND s1.AnimalID= sLAG.AnimalID
các hàng có khả năng tham gia từ các phân vùng khác nhau. Trước tiên tôi muốn sửa truy vấn và sau đó xem xét thay đổi chỉ mục để tránh mọi nhu cầu sắp xếp. ví dụCREATE NONCLUSTERED INDEX [NIX_TCpi] ON [dbo].[Detections_with_Location] ( [XmitID] ASC, [Technology] ASC, [DetectDate] ASC, [ReceiverID] ASC ) INCLUDE ( AnimalID, [Data], [Units], [Location])
COALESCE
câu lệnh tồn tại. Cũng có những trường hợp trong đó nhiều động vật được gắn thẻ có cùng Technology
và XmitID
, nhưng giả định rằng về AnimalID
cơ bản đó là một tập hợp con của kết hợp Technology
* XmitID
. Tôi sẽ thực hiện RANK
trên COALESCE
câu lệnh, nhưng 2008 R2 đưa ra lỗi RANK
khi tổng hợp. Lúc đầu tôi DID có s1.AnimalID= sLAG.AnimalID and s.Technology=sLAG.Technology and s.XmitID=sLAG.XmitID
, nhưng có lỗi tương tự.
COALESCE()
là. Xem xét rằng kết quả được sử dụng để tự tham gia sau đó, nó có thể giết chết hiệu suất. Tôi không biết bạn đã cố gắng sử dụng gợi ý nào về blog đó (định dạng trong blog đó thật kinh khủng và đó không phải là điều kinh khủng duy nhất, mặc dù tên lạ mắt) nhưng tôi chắc chắn có nhiều cách hiệu quả để giải quyết một khoảng trống - và vấn đề -là như của bạn, mà không sử dụng tự tham gia vào các cột được tính toán.