Kế hoạch thực hiện cho thấy hoạt động CONVERT_IMPLICIT đắt tiền. Tôi có thể sửa lỗi này bằng cách lập chỉ mục hay tôi cần thay đổi bảng?


24

Tôi có một cái nhìn thực sự quan trọng, thực sự chậm chạp bao gồm một số điều kiện thực sự xấu xí như thế này trong mệnh đề where của nó. Tôi cũng biết rằng các phép nối là các phép nối thô và chậm varchar(13)thay vì các trường nhận dạng số nguyên, nhưng muốn cải thiện truy vấn đơn giản dưới đây sử dụng chế độ xem này:

CREATE VIEW [dbo].[vwReallySlowView]  AS  
AS  
SELECT     
  I.booking_no_v32 AS bkno, 
  I.trans_type_v41 AS trantype, 
  B.Assigned_to_v61 AS Assignbk, 
  B.order_date AS dateo, B.HourBooked AS HBooked,   
  B.MinBooked AS MBooked, B.SecBooked AS SBooked, 
  I.prep_on AS Pon, I.From_locn AS Flocn, 
  I.Trans_to_locn AS TTlocn,   
                      (CASE I.prep_on WHEN 'Y' THEN I.PDate ELSE I.FirstDate END) AS PrDate, I.PTimeH AS PrTimeH, I.PTimeM AS PrTimeM,   
                      (CASE WHEN I.RetnDate < I.FirstDate THEN I.FirstDate ELSE I.RetnDate END) AS RDatev, I.bit_field_v41 AS bitField, I.FirstDate AS FDatev, I.BookDate AS DBooked,   
                      I.TimeBookedH AS TBookH, I.TimeBookedM AS TBookM, I.TimeBookedS AS TBookS, I.del_time_hour AS dth, I.del_time_min AS dtm, I.return_to_locn AS rtlocn,   
                      I.return_time_hour AS rth, I.return_time_min AS rtm, (CASE WHEN I.Trans_type_v41 IN (6, 7) AND (I.Trans_qty < I.QtyCheckedOut)   
                      THEN 0 WHEN I.Trans_type_v41 IN (6, 7) AND (I.Trans_qty >= I.QtyCheckedOut) THEN I.Trans_Qty - I.QtyCheckedOut ELSE I.trans_qty END) AS trqty,   
                      (CASE WHEN I.Trans_type_v41 IN (6, 7) THEN 0 ELSE I.QtyCheckedOut END) AS MyQtycheckedout, (CASE WHEN I.Trans_type_v41 IN (6, 7)   
                      THEN 0 ELSE I.QtyReturned END) AS retqty, I.ID, B.BookingProgressStatus AS bkProg, I.product_code_v42, I.return_to_locn, I.AssignTo, I.AssignType,   
                      I.QtyReserved, B.DeprepOn,  
        (CASE  B.DeprepOn       
        WHEN 1 THEN  B.DeprepDateTime     
        ELSE   I.RetnDate  
           END)  AS DeprepDateTime, I.InRack 
FROM         dbo.tblItemtran AS I 

INNER JOIN  -- booking_no = varchar(13)
         dbo.tblbookings AS B ON B.booking_no = I.booking_no_v32  --  string inner-join

INNER JOIN  -- product_code = varchar(13) 
        dbo.tblInvmas AS M ON I.product_code_v42 = M.product_code  --  string inner-join

WHERE     (I.trans_type_v41 NOT IN (2, 3, 7, 18, 19, 20, 21, 12, 13, 22)) AND (I.trans_type_v41 NOT IN (6, 7)) AND (I.bit_field_v41 & 4 = 0) OR  
                      (I.trans_type_v41 NOT IN (6, 7)) AND (I.bit_field_v41 & 4 = 0) AND (B.BookingProgressStatus = 1) OR  
                      (I.trans_type_v41 IN (6, 7)) AND (I.bit_field_v41 & 4 = 0) AND (I.QtyCheckedOut = 0) OR  
                      (I.trans_type_v41 IN (6, 7)) AND (I.bit_field_v41 & 4 = 0) AND (I.QtyCheckedOut > 0) AND (I.trans_qty - (I.QtyCheckedOut - I.QtyReturned) > 0)  

Khung nhìn này thường được sử dụng như thế này:

select * from vwReallySlowView
where product_code_v42  = 'LIGHTBULB100W'  -- find "100 watt lightbulb" rows

Khi tôi chạy nó, tôi nhận được mục kế hoạch thực hiện này có giá từ 20 đến 80% tổng chi phí của lô, với vị từ CONVERT_IMPLICIT( .... &(4))cho thấy rằng nó dường như rất chậm khi thực hiện những việc này bitwise boolean testsnhư thế nào (I.ibitfield & 4 = 0).

Tôi không phải là một chuyên gia về MS SQL hoặc tại loại DBA nói chung vì tôi hầu hết là một nhà phát triển phần mềm không phải là SQL. Nhưng tôi nghi ngờ rằng các kết hợp bitwise như vậy là một ý tưởng tồi, và sẽ tốt hơn nếu có các trường boolean rời rạc.

Tôi có thể cải thiện chỉ số này bằng cách nào đó để xử lý tốt hơn chế độ xem này mà không thay đổi lược đồ (đã được sản xuất tại hàng ngàn vị trí) hoặc tôi phải thay đổi bảng bên dưới có một số giá trị boolean được đóng gói thành một số nguyên bit_field_v41để khắc phục vấn đề này ?

Đây là Chỉ mục cụm của tôi tblItemtranđang được quét trong kế hoạch thực hiện này:

-- goal:  speed up  select * from vwReallySlowView where productcode  = 'X'
CREATE CLUSTERED INDEX [idxtblItemTranProductCodeAndTransType] ON [dbo].[tblItemtran] 
(
    [product_code_v42] ASC,  -- varchar(13)
    [trans_type_v41] ASC     -- int
)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]

Đây là kế hoạch thực hiện, đối với một trong những sản phẩm khác dẫn đến chi phí 27% cho CONVERT_IMPLICITvị từ này . cập nhật Lưu ý rằng trong trường hợp này, nút xấu nhất của tôi hiện là "băm khớp" trên một inner joinchi phí 34% Tôi tin rằng đây là chi phí tôi không thể tránh trừ khi tôi có thể tránh tham gia vào các chuỗi mà hiện tại tôi không thể thoát khỏi. Cả hai INNER JOINhoạt động trong chế độ xem ở trên là trên varchar(13)các trường.

Phóng to ở góc dưới bên phải:

nhập mô tả hình ảnh ở đây

Toàn bộ kế hoạch thực hiện như .sqlplan có sẵn trên skydrive. Hình ảnh này chỉ là một cái nhìn tổng quan. Nhấn vào đây để xem hình ảnh của chính nó.

nhập mô tả hình ảnh ở đây

Cập nhật đăng toàn bộ kế hoạch thực hiện. Tôi dường như không thể tìm thấy product_codegiá trị nào là xấu về mặt bệnh lý, nhưng một cách để làm điều đó là select count(*) from viewthay vì làm một sản phẩm. Nhưng các sản phẩm chỉ được sử dụng trong 5% hồ sơ trong bảng cơ bản hoặc ít hơn dường như cho thấy chi phí thấp hơn rất nhiều trong CONVERT_IMPLICIT hoạt động. Nếu tôi định sửa SQL ở đây, tôi nghĩ rằng tôi sẽ sử dụng WHEREmệnh đề thô trong khung nhìn, và tính toán và lưu trữ kết quả của điều kiện mệnh đề khổng lồ đó dưới dạng trường bit "Bao gồm cả phần mềm", trong bảng bên dưới . Presto, vấn đề được giải quyết, phải không?



.QueryPLAN tôi đã đăng là ít bệnh lý hơn so với trường hợp 432k / 17k trong ảnh gốc. Tôi xin lỗi tôi không còn có thể tìm thấy product_codegiá trị tôi đã sử dụng để tạo 87%trường hợp bệnh lý đó với dữ liệu của mình. Những hình ảnh bây giờ cho thấy 27%. Một lần nữa, xin lỗi vì sự nhầm lẫn do chỉnh sửa của tôi.
Warren P

Câu trả lời:


49

Bạn không nên phụ thuộc quá nhiều vào tỷ lệ phần trăm chi phí trong kế hoạch thực hiện. Đây luônchi phí ước tính , ngay cả trong các kế hoạch hậu thực hiện với số 'thực tế' cho những thứ như số hàng. Các chi phí ước tính dựa trên một mô hình hoạt động khá tốt cho mục đích mà nó dự định: cho phép trình tối ưu hóa lựa chọn giữa các kế hoạch thực hiện ứng viên khác nhau cho cùng một truy vấn. Thông tin chi phí rất thú vị và là một yếu tố cần xem xét, nhưng hiếm khi nó phải là một số liệu chính để điều chỉnh truy vấn. Giải thích thông tin kế hoạch thực hiện đòi hỏi một cái nhìn rộng hơn về dữ liệu được trình bày.

Toán tử tìm kiếm mục cụm cụm ItemTran

Tìm kiếm mục cụm cụm mụcTran

Toán tử này thực sự là hai hoạt động trong một. Đầu tiên một hoạt động tìm kiếm chỉ mục tìm thấy tất cả các hàng khớp với vị từ product_code_v42 = 'M10BOLT', sau đó mỗi hàng có vị từ còn lại bit_field_v41 & 4 = 0được áp dụng. Có một chuyển đổi ngầm định bit_field_v41từ loại cơ sở của nó ( tinyinthoặc smallint) sang integer.

Việc chuyển đổi xảy ra do toán tử bit-AND (&) yêu cầu cả hai toán hạng phải cùng loại. Kiểu ẩn của giá trị không đổi '4' là số nguyên và quy tắc ưu tiên loại dữ liệu có nghĩa là bit_field_v41giá trị trường ưu tiên thấp hơn được chuyển đổi.

Vấn đề (chẳng hạn như) có thể dễ dàng sửa chữa bằng cách viết biến vị ngữ là bit_field_v41 & CONVERT(tinyint, 4) = 0- có nghĩa là giá trị không đổi có mức ưu tiên thấp hơn và được chuyển đổi (trong quá trình gấp không đổi) thay vì giá trị cột. Nếu bit_field_v41tinyintkhông có chuyển đổi diễn ra ở tất cả. Tương tự như vậy, CONVERT(smallint, 4)có thể được sử dụng nếu bit_field_v41smallint. Điều đó nói rằng, chuyển đổi không phải là một vấn đề hiệu suất trong trường hợp này, nhưng vẫn nên thực hiện tốt để khớp các loại và tránh chuyển đổi ngầm nếu có thể.

Phần chính của chi phí ước tính cho tìm kiếm này là theo kích thước của bảng cơ sở. Trong khi khóa chỉ mục được phân cụm là hẹp một cách hợp lý, kích thước của mỗi hàng là lớn. Một định nghĩa cho bảng không được đưa ra, nhưng chỉ các cột được sử dụng trong dạng xem thêm vào chiều rộng hàng đáng kể. Vì chỉ mục được nhóm bao gồm tất cả các cột, khoảng cách giữa các khóa chỉ mục được phân cụm là chiều rộng của hàng , không phải chiều rộng của các khóa chỉ mục . Việc sử dụng hậu tố phiên bản trên một số cột cho thấy bảng thực thậm chí còn có nhiều cột hơn cho các phiên bản trước.

Nhìn vào các cột tìm kiếm, vị ngữ dư và đầu ra, hiệu năng của toán tử này có thể được kiểm tra riêng rẽ bằng cách xây dựng truy vấn tương đương (đây 1 <> 2là một mẹo để ngăn chặn tham số tự động, mâu thuẫn được loại bỏ bởi trình tối ưu hóa và không xuất hiện trong kế hoạch truy vấn):

SELECT
    it.booking_no_v32,
    it.QtyCheckedOut,
    it.QtyReturned,
    it.Trans_qty,
    it.trans_type_v41
FROM dbo.tblItemTran AS it
WHERE
    1 <> 2
    AND it.product_code_v42 = 'M10BOLT'
    AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0;

Hiệu năng của truy vấn này với bộ đệm dữ liệu lạnh rất đáng quan tâm, vì việc đọc trước sẽ bị ảnh hưởng bởi sự phân mảnh bảng (chỉ mục cụm). Khóa phân cụm cho bảng này mời phân mảnh, do đó, điều quan trọng là phải duy trì (sắp xếp lại hoặc xây dựng lại) chỉ mục này thường xuyên và sử dụng một khoảng thích hợp FILLFACTORđể cho phép không gian cho các hàng mới giữa các cửa sổ bảo trì chỉ mục.

Tôi đã thực hiện một thử nghiệm về tác động của phân mảnh đối với việc đọc trước bằng cách sử dụng dữ liệu mẫu được tạo bằng SQL Data Generator . Sử dụng cùng một hàng trong bảng được tính như trong kế hoạch truy vấn của câu hỏi, một chỉ mục được phân đoạn cao dẫn đến SELECT * FROM viewmất 15 giây sau DBCC DROPCLEANBUFFERS. Thử nghiệm tương tự trong cùng điều kiện với chỉ mục cụm được xây dựng lại mới trên bảng ItemTrans hoàn thành sau 3 giây.

Nếu dữ liệu bảng thường hoàn toàn trong bộ đệm, thì vấn đề phân mảnh là rất ít quan trọng. Nhưng, ngay cả với độ phân mảnh thấp, các hàng của bảng rộng có thể có nghĩa là số lần đọc logic và vật lý cao hơn nhiều so với dự kiến. Bạn cũng có thể thử nghiệm thêm và xóa phần rõ ràng CONVERTđể xác thực sự mong đợi của tôi rằng vấn đề chuyển đổi ngầm định không quan trọng ở đây, ngoại trừ vi phạm thực tiễn tốt nhất.

Thêm vào đó là số lượng hàng ước tính rời khỏi toán tử tìm kiếm. Ước tính thời gian tối ưu hóa là 165 hàng, nhưng 4.226 được tạo ra tại thời điểm thực hiện. Tôi sẽ trở lại điểm này sau, nhưng lý do chính cho sự khác biệt là do tính chọn lọc của vị từ còn lại (liên quan đến bitwise-AND) rất khó để trình tối ưu hóa dự đoán - thực tế là nó phải đoán.

Toán tử lọc

Toán tử lọc

Tôi đang hiển thị vị từ bộ lọc ở đây chủ yếu để minh họa cách hai NOT INdanh sách được kết hợp, đơn giản hóa và sau đó được mở rộng và cũng để cung cấp một tham chiếu cho cuộc thảo luận khớp băm sau đây. Truy vấn kiểm tra từ tìm kiếm có thể được mở rộng để kết hợp các hiệu ứng của nó và xác định ảnh hưởng của toán tử Bộ lọc đối với hiệu suất:

SELECT
    it.booking_no_v32,
    it.trans_type_v41,
    it.Trans_qty,
    it.QtyReturned,
    it.QtyCheckedOut
FROM dbo.tblItemTran AS it
WHERE
    it.product_code_v42 = 'M10BOLT'
    AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
    AND
    (
        (
            it.trans_type_v41 NOT IN (2, 3, 6, 7, 18, 19, 20, 21, 12, 13, 22)
            AND it.trans_type_v41 NOT IN (6, 7)
        )
        OR
        (
            it.trans_type_v41 NOT IN (6, 7)
        )
        OR 
        (
            it.trans_type_v41 IN (6, 7)
            AND it.QtyCheckedOut = 0
        )
        OR 
        (
            it.trans_type_v41 IN (6, 7)
            AND it.QtyCheckedOut > 0
            AND it.trans_qty - (it.QtyCheckedOut - it.QtyReturned) > 0
        )
    );

Toán tử tính toán vô hướng trong kế hoạch xác định biểu thức sau (chính phép tính được hoãn lại cho đến khi kết quả được yêu cầu bởi toán tử sau):

[Expr1016] = (trans_qty - (QtyCheckedOut - QtyReturned))

Toán tử kết hợp Hash

Việc thực hiện nối trên các kiểu dữ liệu ký tự không phải là lý do cho chi phí ước tính cao của toán tử này. Chú giải công cụ SSMS chỉ hiển thị mục nhập Hash Keys thăm dò, nhưng các chi tiết quan trọng nằm trong cửa sổ Thuộc tính SSMS.

Toán tử Hash Match xây dựng bảng băm bằng cách sử dụng các giá trị của booking_no_v32cột (Hash Keys Build) từ bảng ItemTran, sau đó thăm dò các kết quả khớp bằng booking_nocột (Đầu dò Hash Hash) từ bảng Đặt chỗ. Chú giải công cụ SSMS cũng thường hiển thị Đầu dò dư, nhưng văn bản quá dài đối với một chú giải công cụ và đơn giản là bị bỏ qua.

Một phần dư thăm dò tương tự như phần dư được thấy sau khi chỉ số tìm kiếm trước đó; vị từ còn lại được ước tính trên tất cả các hàng khớp với hàm băm để xác định xem hàng có được truyền cho toán tử cha hay không. Tìm kết quả băm trong bảng băm cân bằng là cực kỳ nhanh, nhưng việc áp dụng một vị từ dư phức tạp cho mỗi hàng khớp với nhau là khá chậm. Chú giải công cụ Hash Match trong Plan Explorer hiển thị chi tiết, bao gồm cả biểu thức thăm dò dư:

Toán tử băm

Vị từ còn lại rất phức tạp và bao gồm kiểm tra trạng thái tiến trình đặt phòng ngay bây giờ cột đó có sẵn từ bảng đặt chỗ. Chú giải công cụ cũng cho thấy sự khác biệt tương tự giữa số lượng hàng ước tính và thực tế được thấy trước đó trong tìm kiếm chỉ mục. Có vẻ kỳ lạ khi phần lớn quá trình lọc được thực hiện hai lần, nhưng đây chỉ là trình tối ưu hóa lạc quan. Người ta không mong đợi các phần của bộ lọc có thể được đẩy xuống kế hoạch từ phần dư của đầu dò để loại bỏ bất kỳ hàng nào (ước tính số hàng giống nhau trước và sau bộ lọc) nhưng trình tối ưu hóa biết rằng nó có thể sai về điều đó. Cơ hội lọc các hàng sớm (giảm chi phí của phép nối băm) xứng đáng với chi phí nhỏ của bộ lọc bổ sung. Toàn bộ bộ lọc không thể được đẩy xuống vì nó bao gồm một bài kiểm tra trên một cột từ bảng đặt chỗ, nhưng hầu hết có thể.

Số lượng hàng bị đánh giá thấp là một vấn đề đối với toán tử Hash Match vì số lượng bộ nhớ dành cho bảng băm dựa trên số lượng hàng ước tính. Trong trường hợp bộ nhớ quá nhỏ so với kích thước của bảng băm cần thiết trong thời gian chạy (do số lượng hàng lớn hơn), bảng băm đệ quy tràn vào bộ lưu trữ tempdb vật lý , thường dẫn đến hiệu suất rất kém. Trong trường hợp xấu nhất, công cụ thực thi dừng đệ quy các thùng băm và khu nghỉ mát đến mức rất chậmthuật toán giải cứu. Tràn băm (đệ quy hoặc giải cứu) là nguyên nhân rất có thể của các vấn đề về hiệu suất được nêu trong câu hỏi (không phải là cột tham gia kiểu ký tự hoặc chuyển đổi ngầm). Nguyên nhân gốc sẽ là do máy chủ dự trữ quá ít bộ nhớ cho truy vấn dựa trên ước tính số lượng hàng (cardinality) không chính xác.

Đáng buồn thay, trước SQL Server 2012, không có dấu hiệu nào trong kế hoạch thực hiện rằng hoạt động băm vượt quá phân bổ bộ nhớ của nó (không thể tăng động sau khi được bảo lưu trước khi bắt đầu thực thi, ngay cả khi máy chủ có khối lượng bộ nhớ trống) và phải tràn vào tempdb. Có thể theo dõi Lớp Sự kiện Cảnh báo Hash bằng Profiler, nhưng có thể khó tương quan các cảnh báo với một truy vấn cụ thể.

Sửa lỗi

Ba vấn đề là phân mảnh, phần còn lại của đầu dò phức tạp trong toán tử khớp băm và ước tính số lượng thẻ không chính xác dẫn đến việc đoán tại chỉ số tìm kiếm.

Giải pháp được đề nghị

Kiểm tra sự phân mảnh và sửa nó nếu cần thiết, lên lịch bảo trì để đảm bảo chỉ số được tổ chức chấp nhận được. Cách thông thường để điều chỉnh ước tính cardinality là cung cấp số liệu thống kê. Trong trường hợp này, trình tối ưu hóa cần số liệu thống kê cho sự kết hợp ( product_code_v42, bitfield_v41 & 4 = 0). Chúng ta không thể tạo số liệu thống kê trực tiếp trên một biểu thức, vì vậy trước tiên chúng ta phải tạo một cột được tính cho biểu thức trường bit, sau đó tạo số liệu thống kê nhiều cột thủ công:

ALTER TABLE dbo.tblItemTran
ADD Bit3 AS bit_field_v41 & CONVERT(tinyint, 4);

CREATE STATISTICS [stats dbo.ItemTran (product_code_v42, Bit3)]
ON dbo.tblItemTran (product_code_v42, Bit3);

Định nghĩa văn bản cột được tính toán phải khớp chính xác với văn bản trong định nghĩa chế độ xem chính xác cho các số liệu thống kê được sử dụng, do đó, việc sửa chế độ xem để loại bỏ chuyển đổi ngầm phải được thực hiện cùng lúc và phải cẩn thận để đảm bảo khớp văn bản.

Các thống kê nhiều cột phải dẫn đến các ước tính tốt hơn nhiều, làm giảm đáng kể khả năng toán tử khớp băm sẽ sử dụng phương pháp đổ đệ quy hoặc thuật toán giải cứu. Thêm cột được tính toán (là hoạt động chỉ siêu dữ liệu và không có khoảng trống trong bảng vì nó không được đánh dấu PERSISTED) và thống kê nhiều cột là phỏng đoán tốt nhất của tôi ở giải pháp đầu tiên.

Khi giải quyết các vấn đề về hiệu năng truy vấn, điều quan trọng là phải đo lường những thứ như thời gian trôi qua, sử dụng CPU, đọc logic, đọc vật lý, loại chờ và thời lượng ... vv. Cũng có thể hữu ích khi chạy các phần của truy vấn một cách riêng biệt để xác thực các nguyên nhân nghi ngờ như được hiển thị ở trên.

Trong một số môi trường, trong đó chế độ xem dữ liệu lên đến từng giây không quan trọng, việc chạy một quy trình nền cụ thể hóa toàn bộ chế độ xem thành bảng chụp nhanh thường xuyên có thể hữu ích. Bảng này chỉ là một bảng cơ sở bình thường và có thể được lập chỉ mục cho các truy vấn đọc mà không lo ảnh hưởng đến hiệu suất cập nhật.

Xem chỉ mục

Đừng cố gắng lập chỉ mục cho quan điểm ban đầu trực tiếp. Hiệu suất đọc sẽ nhanh đến mức đáng kinh ngạc (một lần tìm kiếm trên một chỉ mục xem) nhưng (trong trường hợp này), tất cả các vấn đề về hiệu năng trong các gói truy vấn hiện tại sẽ được chuyển sang các truy vấn sửa đổi bất kỳ cột trong bảng nào được tham chiếu trong dạng xem. Các truy vấn thay đổi các hàng của bảng cơ sở thực sự sẽ bị ảnh hưởng rất xấu.

Giải pháp nâng cao với chế độ xem được lập chỉ mục một phần

Có một giải pháp xem được lập chỉ mục một phần cho truy vấn cụ thể này để sửa các ước tính cardinality và loại bỏ bộ lọc và thăm dò dư, nhưng nó dựa trên một số giả định về dữ liệu (chủ yếu là phỏng đoán của tôi tại lược đồ) và yêu cầu thực hiện chuyên gia, đặc biệt phù hợp các chỉ mục để hỗ trợ các kế hoạch bảo trì xem chỉ mục. Tôi chia sẻ mã dưới đây để quan tâm, tôi không đề xuất bạn thực hiện nó mà không phân tích và kiểm tra rất cẩn thận .

-- Indexed view to optimize the main view
CREATE VIEW dbo.V1
WITH SCHEMABINDING
AS
SELECT
    it.ID,
    it.product_code_v42,
    it.trans_type_v41,
    it.booking_no_v32,
    it.Trans_qty,
    it.QtyReturned,
    it.QtyCheckedOut,
    it.QtyReserved,
    it.bit_field_v41,
    it.prep_on,
    it.From_locn,
    it.Trans_to_locn,
    it.PDate,
    it.FirstDate,
    it.PTimeH,
    it.PTimeM,
    it.RetnDate,
    it.BookDate,
    it.TimeBookedH,
    it.TimeBookedM,
    it.TimeBookedS,
    it.del_time_hour,
    it.del_time_min,
    it.return_to_locn,
    it.return_time_hour,
    it.return_time_min,
    it.AssignTo,
    it.AssignType,
    it.InRack
FROM dbo.tblItemTran AS it
JOIN dbo.tblBookings AS tb ON
    tb.booking_no = it.booking_no_v32
WHERE
    (
        it.trans_type_v41 NOT IN (2, 3, 7, 18, 19, 20, 21, 12, 13, 22)
        AND it.trans_type_v41 NOT IN (6, 7)
        AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
    )
    OR
    (
        it.trans_type_v41 NOT IN (6, 7)
        AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
        AND tb.BookingProgressStatus = 1
    )
    OR 
    (
        it.trans_type_v41 IN (6, 7)
        AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
        AND it.QtyCheckedOut = 0
    )
    OR 
    (
        it.trans_type_v41 IN (6, 7)
        AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
        AND it.QtyCheckedOut > 0
        AND it.trans_qty - (it.QtyCheckedOut - it.QtyReturned) > 0
    );
GO
CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.V1 (product_code_v42, ID);
GO

Chế độ xem hiện tại được điều chỉnh để sử dụng chế độ xem được lập chỉ mục ở trên:

CREATE VIEW [dbo].[vwReallySlowView2]
AS
SELECT
    I.booking_no_v32 AS bkno,
    I.trans_type_v41 AS trantype,
    B.Assigned_to_v61 AS Assignbk,
    B.order_date AS dateo,
    B.HourBooked AS HBooked,
    B.MinBooked AS MBooked,
    B.SecBooked AS SBooked,
    I.prep_on AS Pon,
    I.From_locn AS Flocn,
    I.Trans_to_locn AS TTlocn,
    CASE I.prep_on 
        WHEN 'Y' THEN I.PDate
        ELSE I.FirstDate
    END AS PrDate,
    I.PTimeH AS PrTimeH,
    I.PTimeM AS PrTimeM,
    CASE
        WHEN I.RetnDate < I.FirstDate 
        THEN I.FirstDate 
        ELSE I.RetnDate
    END AS RDatev,
    I.bit_field_v41 AS bitField,
    I.FirstDate AS FDatev,
    I.BookDate AS DBooked,
    I.TimeBookedH AS TBookH,
    I.TimeBookedM AS TBookM,
    I.TimeBookedS AS TBookS,
    I.del_time_hour AS dth,
    I.del_time_min AS dtm,
    I.return_to_locn AS rtlocn,
    I.return_time_hour AS rth,
    I.return_time_min AS rtm,
    CASE
        WHEN
            I.Trans_type_v41 IN (6, 7) 
            AND I.Trans_qty < I.QtyCheckedOut
            THEN 0 
        WHEN
            I.Trans_type_v41 IN (6, 7)
            AND I.Trans_qty >= I.QtyCheckedOut
            THEN I.Trans_Qty - I.QtyCheckedOut
        ELSE
            I.trans_qty
    END AS trqty,
    CASE
        WHEN I.Trans_type_v41 IN (6, 7)
        THEN 0
        ELSE I.QtyCheckedOut
    END AS MyQtycheckedout,
    CASE
        WHEN I.Trans_type_v41 IN (6, 7)
        THEN 0
        ELSE I.QtyReturned
    END AS retqty,
    I.ID,
    B.BookingProgressStatus AS bkProg,
    I.product_code_v42,
    I.return_to_locn,
    I.AssignTo,
    I.AssignType,
    I.QtyReserved,
    B.DeprepOn,
    CASE B.DeprepOn
        WHEN 1 THEN B.DeprepDateTime
        ELSE I.RetnDate
    END AS DeprepDateTime,
    I.InRack
FROM dbo.V1 AS I WITH (NOEXPAND)
JOIN dbo.tblbookings AS B ON
    B.booking_no = I.booking_no_v32
JOIN dbo.tblInvmas AS M ON
    I.product_code_v42 = M.product_code;

Ví dụ truy vấn và kế hoạch thực hiện:

SELECT
    vrsv.*
FROM dbo.vwReallySlowView2 AS vrsv
WHERE vrsv.product_code_v42 = 'M10BOLT';

Kế hoạch thực hiện mới

Trong kế hoạch mới, kết quả băm không có biến vị ngữ còn lại , không có bộ lọc phức tạp , không có biến vị ngữ còn lại trên chế độ xem được lập chỉ mục và ước tính chính xác là chính xác.

Như một ví dụ về cách các gói chèn / cập nhật / xóa sẽ bị ảnh hưởng, đây là kế hoạch chèn vào bảng ItemTrans:

Chèn kế hoạch

Phần được tô sáng là mới và cần thiết để bảo trì chế độ xem được lập chỉ mục. Bộ đệm bảng phát lại các hàng của bảng cơ sở được chèn để bảo trì chế độ xem được lập chỉ mục. Mỗi hàng được nối với bảng đặt chỗ bằng cách tìm kiếm chỉ mục được nhóm, sau đó bộ lọc áp dụng các WHEREvị từ mệnh đề phức tạp để xem liệu hàng đó có cần được thêm vào dạng xem không. Nếu vậy, một phần chèn được thực hiện theo chỉ mục được nhóm.

SELECT * FROM viewThử nghiệm tương tự được thực hiện trước đó đã hoàn thành trong 150ms với chế độ xem được lập chỉ mục.

Điều cuối cùng: Tôi nhận thấy máy chủ 2008 R2 của bạn vẫn ở RTM. Nó sẽ không khắc phục được các vấn đề về hiệu suất của bạn, nhưng Gói dịch vụ 2 cho 2008 R2 đã có sẵn từ tháng 7 năm 2012 và có nhiều lý do chính đáng để duy trì hiện tại nhất có thể với các gói dịch vụ.

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.