Triển khai chì / Lag trong SQL Server 2008 R2: Đã vượt quá bộ nhớ tối đa


7

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 Locationtrì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).

LAGLEADkhông có sẵn trong SQL Server 2008R2 (cũng không có UNBOUNDED PRECEDINGtrong PARTITIONmệ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 AnimalIDkhô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.TagSNlà (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 NONCLUSTEREDphi UNIQUEtạ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ể

  1. 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.

  2. 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)

  3. Đã 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 sdướ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

INSERTchi phí 0%
SEQUENCEchi 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_Acó chi phí 9% cho Index InsertNIX_TCDcũng không NIX_FSortbước nào; Các Table Spoolcho NIX_Flà miễn phí.
Các Clustered Index Insertchi phí là 10%.
Ngoài ra còn có Sortchi phí 2% và Parallelismchi phí 1% cho phân phối luồng.
Đối với các SEQUENCEchi 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 Spoolchuỗ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

  1. Bất kỳ đề xuất để cải thiện?

  2. Tôi có thể phân vùng khi tôi tham gia các bản sao của s?

  3. Mọi thứ sẽ được cải thiện nếu tôi lập sthà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?

  4. Sẽ hiệu quả hơn khi tạo các UNIQUEchỉ 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

  1. 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.



1
Bạn có nhớ đăng một số dữ liệu là tốt? Sẽ dễ dàng để xây dựng một repro và giúp bạn ra ngoài. Ngoài ra, truy vấn nên có cast(det.XmitID AS nvarchar(10)), N'BSVALUE999'<- hãy nhớ rằng nvarchar không có chiều dài và Nkế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.
Kin Shah

5
Truy vấn hiện tại của bạn không chính xác. Bạn đang làm RANK() OVER (PARTITION BY det.Technology, det.XmitID ORDER BY DetectDate ASC, ReceiverID ASC) as DetIDnhư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])
Martin Smith

Điểm tốt tái lập chỉ mục. Vấn đề không phải là tất cả các động vật được gắn thẻ đều có trong cơ sở dữ liệu, đó là lý do tại sao sự kết hợp bên trong COALESCEcâ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 TechnologyXmitID, nhưng giả định rằng về AnimalIDcơ 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 RANKtrên COALESCEcâu lệnh, nhưng 2008 R2 đưa ra lỗi RANKkhi 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ự.
mpag

Bạn chưa hiển thị dữ liệu mẫu. Tôi tự hỏi những gì cần thiết cho việc này 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.
ypercubeᵀᴹ

Câu trả lời:


5

Tôi đang gửi câu trả lời này vì tôi hiện đang tránh các lỗi loại hết bộ nhớ cũng như đã giảm thời gian chạy đáng kể (là hơn 4 giờ, kết thúc trong thất bại; bây giờ là 1,25 giờ, kết thúc thành công ). Tuy nhiên, tôi chắc chắn rằng sau khoảng 10 triệu hồ sơ nữa, vấn đề này có thể xuất hiện trở lại, vì vậy tôi sẽ đánh giá cao bất kỳ nhận xét hoặc câu trả lời bổ sung nào nhằm mục đích làm cho bộ nhớ này hiệu quả hơn trong tương lai.

"Giải pháp" cho đến thời điểm này là loại bỏ các trường không cần thiết và đặc biệt là các chỉ số từ thiết kế của các bảng tạm thời. Ngoài ra, việc tạo chỉ mục cho các khóa không ràng buộc đã được hoãn lại cho đến khi bảng được điền.

Để giải quyết vấn đề (được chỉ ra trước tiên bởi @MartinSmith) về việc phân vùng không khớp với sau này JOIN, tôi đã tạo một trường trong truy vấn con mà sau đó tôi sử dụng cho cả PARTITIONing và JOINing.

Mã cho Q

set nocount on;
SET XACT_ABORT ON;
SELECT
    cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
    'started' as reason; --last run 2015-12-16 18:22:02
GO

CREATE TABLE ##ttOrder_det (
    AnimalID nvarchar(50) not null,
    DD DateTime not null,
    ReceiverID int NOT NULL,
    Location nvarchar(255) NOT NULL,
    GLocation nvarchar(255) NULL,
    DetID int NOT NULL,
    BinIncORNum int NULL, -- first pass=Inc, second pass=Num
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 UNIQUE INDEX UX_CTR ON ##ttOrder_det (AnimalID ASC, DetID ASC);
SELECT
    cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
   'created first temporary table' as reason;  --last run 2015-12-16 18:22:02
GO
WITH s AS (
    SELECT 
        AnimalID, DetectDate,
        ReceiverID, Location, GLocation,
        ROW_NUMBER() OVER (
            PARTITION BY AnimalID ORDER BY DetectDate ASC, ReceiverID ASC
        ) as DetID
    FROM (
        SELECT 
            COALESCE (
                TF.AnimalID,
                Det.Technology+'-'+cast(Det.XmitID AS nvarchar(10)),
                Det.AnimalID,
                N'BSVALUE999'
            ) as AnimalID,
            DetectDate,
            ReceiverID,
            COALESCE (
                Det.location,
                N'Unknown Location'
            ) as Location,
            COALESCE (
                ML.General_Location,
                N'Invalid General Location - Orphaned Receiver'
            ) as GLocation
        FROM
            Detections_with_Location as Det LEFT OUTER JOIN
            Receiver_Locations as ML ON Det.Location=ML.Location LEFT OUTER JOIN
            Tagged_Animal as TF ON Det.AnimalID=TF.AnimalID
    ) AS T
)
INSERT INTO ##ttOrder_det (AnimalID, DD, ReceiverID, Location, GLocation, DetID, BinIncORNum)
    SELECT 
        s1.AnimalID,
        s1.DetectDate, s1.ReceiverID, s1.Location, s1.GLocation,
        s1.DetID, 
        CASE WHEN sLg.DetectDate IS NULL
            THEN 1 
            ELSE CASE WHEN sLg.GLocation = s1.GLocation
                THEN 0
                ELSE 1
            END
        END AS BinInc
    FROM s as s1
    LEFT OUTER JOIN s AS sLg ON
        s1.AnimalID= sLg.AnimalID AND
        s1.DetID = sLg.DetID + 1
SELECT
    cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
   'filled first temp table' as reason,
   COUNT(*) as SizeOfFirstTemp FROM ##ttOrder_det; --2015-12-16 18:43:03, 46627879
GO
CREATE NONCLUSTERED INDEX NIX_F on ##ttOrder_det (AnimalID ASC);
CREATE NONCLUSTERED INDEX NIX_R ON ##ttOrder_det (DetID ASC);
--dropped several additional indices: `NIX_`s VTC, TCD, A, DD, Bi
SELECT
    cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
    'indexed first temp table' as reason; --2015-12-16 18:44:12
GO

Nhận xét nhanh

Tôi chuyển sang sử dụng ROW_NUMBERthay vì RANK. Điều này là không xác định, nhưng ít nhất sẽ không dẫn đến "mối quan hệ", điều này sẽ dẫn đến việc phá vỡ việc LAGthực hiện xung quanh điểm đó. Các mối quan hệ không nên tồn tại, nhưng đây chỉ là bằng chứng trong tương lai chống lại General_Locationcác s rất gần nhau mà cùng phát hiện cùng một truyền.

Một lần nữa, như hai người dùng đã chỉ ra trong các nhận xét ở trên, tôi không sử dụng PK đầy đủ của Tagged_Animalbảng, do đó, có khả năng có JOINmột điều không rõ ràng AnimalID. Tuy nhiên, hiện tại, cả AnimalIDTagSNđang UNIQUE, mặc dù không bị ràng buộc.

Tôi đã lên kế hoạch từ bỏ ReceiverIDlĩnh vực này để sử dụng Location, nhưng tôi đã có một khoảng thời gian có hai Người nhận được triển khai tại cùng một địa điểm (một người nhận được cho là bị mất nhưng sau đó đã tìm thấy) thực sự phát hiện cùng một con vật

Mã theo dõi để hoàn thành nhiệm vụ

CREATE TABLE ##ttOrder_det2 (
    AnimalID nvarchar(50) not null,
    DetID int NOT NULL,
    BinNum int NULL,
CONSTRAINT [PK_ttRDA2] PRIMARY KEY CLUSTERED 
    ([AnimalID] ASC, [DetID] 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
SELECT
    cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
    'second temp table created' as reason; --2015-12-16 18:44:15
GO
-- SET XACT_ABORT ON will cause the transaction to be uncommittable
-- when the constraint violation occurs. 
BEGIN TRANSACTION
  BEGIN TRY
   DECLARE @AnimalID as nvarchar(50);
    DECLARE @DetID as int;
    DECLARE @BinInc as int;
    DECLARE @BinNum as int;
    DECLARE @AnimalVisit as CURSOR;
    SET @AnimalVisit = CURSOR FOR SELECT AnimalID, DetID, BinIncORNum FROM ##ttOrder_det ORDER BY AnimalID, DetID;
    OPEN @AnimalVisit;
    FETCH NEXT FROM @AnimalVisit INTO @AnimalID, @DetID, @BinInc;
    WHILE @@FETCH_STATUS = 0
      BEGIN
        IF (@DetID <= 1) SET @BinNum = 0;
        SET @BinNum += @BinInc;
        INSERT INTO ##ttOrder_det2 (AnimalID, DetID, BinNum) VALUES (@AnimalID, @DetID, @BinNum);
        FETCH NEXT FROM @AnimalVisit INTO @AnimalID, @DetID, @BinInc;
      END
    CLOSE @AnimalVisit;
    DEALLOCATE @AnimalVisit;
  END TRY
  BEGIN CATCH
    exec sp_lock; -- added to display the open locks after the timeout
--    exec sp_who2; -- shows the active processes
    EXECUTE usp_GetErrorInfo;
    --RETURN -- ignoring this error for brevity
        -- Test XACT_STATE:
        -- If 1, the transaction is committable.
        -- If -1, the transaction is uncommittable and should 
        --     be rolled back.
        -- XACT_STATE = 0 means that there is no transaction and
        --     a commit or rollback operation would generate an error.

    -- Test whether the transaction is uncommittable.
    IF (XACT_STATE()) = -1
    BEGIN
        SELECT
            cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
            'The transaction is in an uncommittable state. Rolling back transaction.' as reason
            SET XACT_ABORT off
            RETURN -- 1 --error
        ROLLBACK TRANSACTION;
    END;
    -- Test whether the transaction is committable.
    IF (XACT_STATE()) = 1
    BEGIN
        SELECT
            cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
            'The transaction is committable. Committing transaction.' as reason
        COMMIT TRANSACTION;   
    END;
  END CATCH;
  IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO
SELECT 
    cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
    'filled second temp table' as reason,
    COUNT(*) as Table2Size from ##ttOrder_det2; --2015-12-16 19:11:17, 46627879
GO
CREATE NONCLUSTERED INDEX NIX_CT2 ON ##ttOrder_det2 (AnimalID ASC);
CREATE NONCLUSTERED INDEX NIX_R2 ON ##ttOrder_det2 (DetID ASC);
SELECT
    cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
    'indexed second temp table' as reason;
--EXEC tempdb.dbo.usp_PruneTemp;
GO
BEGIN TRANSACTION
    BEGIN TRY
        UPDATE a
            SET a.BinIncORNum=b.BinNum
        FROM ##ttOrder_det AS a
        INNER JOIN ##ttOrder_det2 AS b ON 
            a.AnimalID=b.AnimalID AND a.DetID=b.DetID;
        SELECT
            cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
            'backfilled first temp table with info from second table' as reason,
            @@ROWCOUNT as EntriesAffected;  --2015-12-16 19:19:54, 46627879
        DROP TABLE ##ttOrder_det2;
        COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        SELECT name, log_reuse_wait_desc FROM sys.databases
        SELECT
          cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
          'ERROR: backfilling first temp table, see sys.databases info' as reason;
        EXECUTE usp_GetErrorInfo;
        IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
        SET XACT_ABORT off
        RETURN --1 --error
    END CATCH
--IF @@TRANCOUNT > 0 COMMIT TRANSACTION
GO
CREATE TABLE derived__AnimalVisits (
    AnimalID nvarchar(50) not null,
    DetectDate DateTime not null,
    ReceiverID int NOT NULL,
    Location nvarchar(255) NOT NULL,
    GeneralLocation nvarchar(255) NULL,
    DetOrder int NOT NULL,
    VisitNum int NOT NULL,
CONSTRAINT [PK_dFV] PRIMARY KEY CLUSTERED 
    (AnimalID ASC, DetectDate 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 UNIQUE INDEX UX_CTR ON derived__AnimalVisits (AnimalID ASC, DetOrder ASC);
SELECT 
    cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
    'created persistent derived table' as reason; --2015-12-16 19:20:53
GO

--DECLARE @FVError as int = 0;
BEGIN TRY
    INSERT INTO derived__AnimalVisits (AnimalID, DetectDate, ReceiverID, Location, GeneralLocation, DetOrder, VisitNum)
        SELECT AnimalID, DD, ReceiverID, Location, GLocation, COALESCE(DetID,0), COALESCE(BinIncORNum,0) FROM ##ttOrder_det;
END TRY
BEGIN CATCH
    SELECT
        cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
        'ERROR: filling persistent derived table' as reason;
    EXECUTE usp_GetErrorInfo;
    SET XACT_ABORT off
    RETURN --1 --error
END CATCH
CREATE NONCLUSTERED INDEX NIX_CT ON derived__AnimalVisits (AnimalID ASC);
CREATE NONCLUSTERED INDEX NIX_VTC ON derived__AnimalVisits (ReceiverID ASC, AnimalID ASC);
CREATE NONCLUSTERED INDEX NIX_TCD ON derived__AnimalVisits (AnimalID ASC, DetectDate ASC);
CREATE NONCLUSTERED INDEX NIX_R ON derived__AnimalVisits (DetOrder ASC);
CREATE NONCLUSTERED INDEX NIX_Bi ON derived__AnimalVisits (VisitNum ASC);
SELECT
    cast(cast(current_timestamp as datetime2) as varchar(19)) as time,
    'indexed / now cleaning up' as reason; --2015-12-16 19:31:18
GO
IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE id = OBJECT_ID(N'[tempdb].[dbo].[##ttOrder_det2]') AND xtype=N'U')
    DROP TABLE tempdb.[dbo].[##ttOrder_det2];
IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE id = OBJECT_ID(N'[tempdb].[dbo].[##ttOrder_det]') AND xtype=N'U')
    DROP TABLE tempdb.[dbo].[##ttOrder_det];
SET XACT_ABORT off
--cleaning up of transaction logs, etc done at 2015-12-16 19:39:07
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.