Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Tiếp theo về Summer Performance Palooza 2013

Vào ngày 27 tháng 6, Chương trình Ảo về Hiệu suất PASS đã tổ chức Palooza Biểu diễn Mùa hè 2013 - một chương trình 24 Giờ PASS được thu nhỏ lại, nhưng chỉ tập trung vào các chủ đề liên quan đến hiệu suất. Tôi đã đưa ra một phiên thảo luận có tên "10 thói quen xấu có thể giết chết hiệu suất", đề cập đến 10 khái niệm sau:

  1. CHỌN *
  2. Chỉ mục mù
  3. Không có tiền tố lược đồ
  4. Tùy chọn con trỏ mặc định
  5. tiền tố
  6. sp_
  7. Cho phép bộ nhớ cache phình ra
  8. Các loại dữ liệu rộng
  9. Máy chủ SQL mặc định
  10. Lạm dụng các chức năng
  11. "Hoạt động trên máy của tôi"

Bạn có thể nhớ một số chủ đề này từ các bài thuyết trình như bài nói chuyện "Thói quen xấu và phương pháp hay nhất" của tôi hoặc hội thảo trên web Điều chỉnh truy vấn hàng tuần mà tôi đã tổ chức cùng Kevin Kline từ đầu tháng 6 đến hết tuần này. (Nhân tiện, 6 video đó sẽ ra mắt vào đầu tháng 8 trên YouTube.)

Phiên của tôi có 351 người tham dự và tôi đã nhận được một số phản hồi tuyệt vời. Tôi muốn giải quyết một số vấn đề đó.

Đầu tiên, một vấn đề về cấu hình:Tôi đang sử dụng một micrô hoàn toàn mới và không biết rằng mỗi lần nhấn phím sẽ phát ra âm thanh như sấm sét. Tôi đã giải quyết vấn đề đó bằng cách bố trí tốt hơn các thiết bị ngoại vi của mình, nhưng tôi muốn gửi lời xin lỗi đến những người bị ảnh hưởng bởi điều đó.

Tiếp theo, tải xuống; bộ bài và các mẫu được đăng lên địa điểm tổ chức sự kiện. Chúng ở cuối trang, nhưng bạn cũng có thể tải chúng xuống ngay tại đây.

Cuối cùng, những gì sau đây là danh sách các câu hỏi đã được đăng trong phiên họp và tôi muốn đảm bảo rằng tôi đã giải quyết bất kỳ câu hỏi nào chưa được trả lời trong phần Hỏi &Đáp trực tiếp. Tôi xin lỗi vì tôi đã giải quyết vấn đề này chỉ trong vòng chưa đầy một tháng. , nhưng có đã rất nhiều câu hỏi và tôi không muốn xuất bản chúng thành từng phần.

Hỏi:Nếu bạn có một proc có thể có các giá trị đầu vào khác nhau rất nhiều cho các tham số đã cho và kết quả là kế hoạch đã lưu trong bộ nhớ cache không tối ưu cho hầu hết các trường hợp, thì tốt nhất là tạo proc VỚI RECOMPILE và sử dụng một ít hiệu suất đạt được mỗi khi nó chạy?

A: Bạn sẽ phải tiếp cận vấn đề này theo từng trường hợp cụ thể, vì nó thực sự sẽ phụ thuộc vào nhiều yếu tố (bao gồm cả độ phức tạp của kế hoạch). Cũng lưu ý rằng bạn có thể biên dịch lại mức câu lệnh sao cho chỉ những câu lệnh bị ảnh hưởng mới phải thực hiện, trái ngược với toàn bộ mô-đun. Paul White đã nhắc tôi rằng mọi người thường 'sửa chữa' khả năng đánh hơi tham số bằng RECOMPILE , nhưng quá thường xuyên, điều đó có nghĩa là WITH RECOMPILE kiểu 2000 hơn là OPTION (RECOMPILE) tốt hơn nhiều , không chỉ giới hạn chính nó trong câu lệnh mà còn cho phép nhúng tham số, WITH RECOMPILE không làm. Vì vậy, nếu bạn định sử dụng RECOMPILE để ngăn chặn việc dò tìm tham số, hãy thêm nó vào câu lệnh, không phải mô-đun.

Hỏi:Nếu bạn sử dụng biên dịch lại tùy chọn trên sql động, bạn có thấy hiệu suất thành công lớn không

A: Như ở trên, điều này sẽ phụ thuộc vào chi phí và độ phức tạp của các kế hoạch và không có cách nào để nói, "Đúng, sẽ luôn có một thành công lớn." Bạn cũng phải chắc chắn so sánh cái đó với cái thay thế.

Hỏi:Nếu có chỉ mục nhóm trên insertdate, sau này khi truy xuất dữ liệu, chúng tôi sử dụng hàm chuyển đổi, nếu sử dụng so sánh trực tiếp, ngày truy vấn không thể đọc được, trong thế giới thực, lựa chọn tốt hơn là gì

A: Tôi không chắc "có thể đọc được trong thế giới thực" nghĩa là gì. Nếu bạn muốn đầu ra ở một định dạng cụ thể, bạn thường nên chuyển đổi thành một chuỗi ở phía máy khách. C # và hầu hết các ngôn ngữ khác mà bạn có thể đang sử dụng ở cấp bản trình bày có nhiều khả năng định dạng đầu ra ngày / giờ từ cơ sở dữ liệu ở bất kỳ định dạng khu vực nào bạn muốn.

Hỏi:Làm cách nào để xác định số lần một gói được lưu trong bộ nhớ cache được sử dụng - có cột có giá trị đó hay bất kỳ truy vấn nào trên internet sẽ cung cấp giá trị này không? Cuối cùng, số lượng như vậy có phải chỉ phù hợp kể từ lần khởi động lại cuối cùng không?

A: Hầu hết các DMV chỉ có hiệu lực kể từ lần dịch vụ cuối cùng bắt đầu, và thậm chí những DMV khác có thể được xả thường xuyên hơn (thậm chí theo yêu cầu - cả vô tình và cố ý). Tất nhiên, bộ nhớ cache kế hoạch luôn hoạt động liên tục và các kế hoạch AFAIK thoát ra khỏi bộ nhớ cache sẽ không duy trì số lượng trước đó của chúng nếu chúng xuất hiện trở lại. Vì vậy, ngay cả khi bạn nhìn thấy một kế hoạch trong bộ nhớ cache, tôi cũng không 100% tự tin rằng bạn có thể tin vào số lần sử dụng mà bạn tìm thấy.

Điều đó nói rằng, những gì bạn có thể đang tìm kiếm là sys.dm_exec_cached_plans.usecounts và bạn cũng có thể tìm thấy sys.dm_exec_procedure_stats.execution_count để giúp bổ sung thông tin cho các thủ tục trong đó các câu lệnh riêng lẻ trong các thủ tục không được tìm thấy trong bộ nhớ đệm.

Hỏi:Vấn đề xảy ra khi nâng cấp công cụ db lên phiên bản mới nhưng vẫn để cơ sở dữ liệu người dùng ở chế độ tương thích cũ hơn là gì?

A: Mối quan tâm chính xung quanh vấn đề này là khả năng sử dụng một số cú pháp nhất định, chẳng hạn như OUTER APPLY hoặc các biến với một hàm có giá trị bảng. Tôi không biết về bất kỳ trường hợp nào mà việc sử dụng khả năng tương thích thấp hơn có bất kỳ tác động trực tiếp nào đến hiệu suất, nhưng một số điều thường được khuyến nghị là xây dựng lại chỉ mục và cập nhật thống kê (và yêu cầu nhà cung cấp của bạn hỗ trợ mức độ tương thích mới hơn càng sớm càng tốt). Tôi đã thấy nó giải quyết được tình trạng suy giảm hiệu suất không mong muốn trong một số trường hợp đáng kể, nhưng tôi cũng đã nghe một số ý kiến ​​cho rằng làm như vậy là không cần thiết và thậm chí có thể là không khôn ngoan.

Hỏi:Trên * có vấn đề gì không khi thực hiện một mệnh đề tồn tại

A: Không, ít nhất là về mặt hiệu suất, một ngoại lệ trong đó SELECT * không thành vấn đề khi được sử dụng bên trong EXISTS mệnh đề. Nhưng tại sao bạn lại sử dụng * đây? Tôi thích sử dụng EXISTS (SELECT 1 ... - trình tối ưu hóa sẽ xử lý những thứ đó giống nhau, nhưng theo cách nó tự ghi lại mã và đảm bảo rằng người đọc hiểu truy vấn con sẽ không trả về bất kỳ dữ liệu nào (ngay cả khi họ bỏ lỡ EXISTS lớn ở ngoài). Một số người sử dụng NULL và tôi không biết tại sao tôi bắt đầu sử dụng 1, nhưng tôi tìm thấy NULL hơi không trực quan.

* Lưu ý * bạn sẽ cần phải cẩn thận, nếu bạn cố gắng sử dụng EXISTS (SELECT * bên trong mô-đun bị ràng buộc giản đồ:

CREATE VIEW dbo.ThisWillNotWork
WITH SCHEMABINDING
AS
  SELECT BusinessEntityID
    FROM Person.Person AS p
	WHERE EXISTS (SELECT * FROM Sales.SalesOrderHeader AS h
	  WHERE h.SalesPersonID = p.BusinessEntityID);

Bạn gặp lỗi này:

Msg 1054, Mức 15, Trạng thái 6, Thủ tục ThisWillNotWork, Dòng 6
Cú pháp '*' không được phép trong các đối tượng liên kết lược đồ.

Tuy nhiên, thay đổi nó thành SELECT 1 hoạt động tốt. Vì vậy, có thể đó là một đối số khác để tránh SELECT * ngay cả trong trường hợp đó.

Hỏi:Có bất kỳ liên kết tài nguyên nào cho các tiêu chuẩn mã hóa tốt nhất không?

A: Có lẽ có hàng trăm ngôn ngữ khác nhau. Giống như các quy ước đặt tên, các tiêu chuẩn mã hóa là một điều rất chủ quan. Không quan trọng quy ước nào bạn quyết định phù hợp nhất với bạn; nếu bạn thích tbl tiền tố, bắt đầu đi! Thích Pascal hơn bigEndian, có nó. Muốn thêm tiền tố tên cột của bạn với kiểu dữ liệu, như intCustomerID , Tôi sẽ không ngăn cản bạn. Điều quan trọng hơn là bạn xác định một quy ước và sử dụng nó * một cách nhất quán. *

Điều đó nói lên rằng, nếu bạn muốn ý kiến ​​của tôi, tôi không thiếu chúng.

H:XACT_ABORT có thể được sử dụng trong SQL Server 2008 trở đi không?

A: Tôi không biết có kế hoạch nào sẽ ngừng sử dụng XACT_ABORT vì vậy nó sẽ tiếp tục hoạt động tốt. Thành thật mà nói, tôi không thấy điều này được sử dụng thường xuyên vì bây giờ chúng tôi có TRY / CATCH (và THROW kể từ SQL Server 2012).

H:Làm thế nào để một Hàm Bảng Nội tuyến trên một chéo áp dụng so với hàm vô hướng được gọi là 1.000x?

A: Tôi đã không kiểm tra điều này, nhưng trong nhiều trường hợp, việc thay thế một hàm vô hướng bằng một hàm có giá trị bảng nội tuyến có thể có tác động lớn đến hiệu suất. Vấn đề tôi nhận thấy là việc thực hiện chuyển đổi này có thể là một lượng lớn công việc trên hệ thống được viết trước APPLY đã tồn tại hoặc vẫn được quản lý bởi những người chưa chấp nhận cách tiếp cận tốt hơn này.

H:Tôi có một truy vấn chạy rất chậm lần đầu tiên khoảng (~ 1 phút) và nhanh (~ 3 giây) mọi lúc. Tôi sẽ bắt đầu xem vấn đề hiệu suất đến từ đâu trong lần đầu tiên?

A: Bạn cần lưu ý đến hai điều:(1) độ trễ liên quan đến thời gian biên dịch hoặc (2) độ trễ liên quan đến lượng dữ liệu đang được tải để đáp ứng truy vấn và lần đầu tiên nó phải đến từ đĩa và không phải bộ nhớ. Đối với (1), bạn có thể thực hiện truy vấn trong SQL Sentry Plan Explorer và thanh trạng thái sẽ hiển thị cho bạn thời gian biên dịch cho các lần gọi đầu tiên và tiếp theo (mặc dù một phút có vẻ khá thừa cho việc này và không chắc). Nếu bạn không tìm thấy bất kỳ sự khác biệt nào, thì đó có thể chỉ là bản chất của hệ thống:không đủ bộ nhớ để hỗ trợ lượng dữ liệu bạn đang cố gắng tải với truy vấn này kết hợp với dữ liệu khác đã có trong vùng đệm. Nếu bạn không tin rằng một trong hai điều này là vấn đề, thì hãy xem liệu hai lần thực thi khác nhau có thực sự mang lại các kế hoạch khác nhau hay không - nếu có bất kỳ sự khác biệt nào, hãy đăng các kế hoạch lên answer.sqlperformance.com và chúng tôi sẽ sẵn lòng xem xét . Trên thực tế, việc nắm bắt các kế hoạch thực tế cho cả hai lần thực thi bằng cách sử dụng Plan Explorer trong mọi trường hợp cũng có thể cho bạn biết về bất kỳ sự khác biệt nào trong I / O và có thể dẫn đến việc SQL Server dành thời gian cho lần chạy đầu tiên, chậm hơn.

Hỏi:Tôi đang sử dụng sp_executesql để kiểm tra thông số, liệu Optimize cho khối lượng công việc đặc biệt có giải quyết được điều này vì chỉ có sơ khai kế hoạch nằm trong bộ nhớ cache không?

A: Không, tôi không nghĩ rằng cài đặt Tối ưu hóa cho khối lượng công việc đột xuất sẽ giúp ích cho trường hợp này, vì đánh giá tham số ngụ ý rằng các lần thực thi tiếp theo của cùng một kế hoạch được sử dụng cho các tham số khác nhau và với các hành vi hiệu suất khác nhau đáng kể. Tối ưu hóa cho khối lượng công việc đặc biệt được sử dụng để giảm thiểu tác động mạnh mẽ đến bộ đệm kế hoạch có thể xảy ra khi bạn có nhiều câu lệnh SQL khác nhau. Vì vậy, trừ khi bạn đang nói về tác động đến bộ nhớ cache kế hoạch của nhiều câu lệnh khác nhau, bạn đang gửi đến sp_executesql - điều này sẽ không được coi là đánh giá thông số - tôi nghĩ đang thử nghiệm với OPTION (RECOMPILE) có thể có kết quả tốt hơn hoặc nếu bạn biết các giá trị tham số * do * tạo ra kết quả tốt trên nhiều kết hợp tham số khác nhau, hãy sử dụng OPTIMIZE FOR . Câu trả lời này của Paul White có thể cung cấp cái nhìn sâu sắc hơn nhiều.

Hỏi:Có cách nào để chạy SQL động và KHÔNG lưu kế hoạch truy vấn không?

A: Chắc chắn, chỉ cần bao gồm OPTION (RECOMPILE) trong văn bản SQL động:

DBCC FREEPROCCACHE;
 
USE AdventureWorks2012;
GO
SET NOCOUNT ON;
GO
 
EXEC sp_executesql 
  N'SELECT TOP (1) * INTO #x FROM Sales.SalesOrderHeader;';
GO
EXEC sp_executesql 
  N'SELECT TOP (1) * INTO #x FROM Sales.SalesOrderDetail OPTION (RECOMPILE);'
GO
 
SELECT t.[text], p.usecounts
FROM sys.dm_exec_cached_plans AS p
CROSS APPLY sys.dm_exec_sql_text(p.[plan_handle]) AS t
WHERE t.[text] LIKE N'%Sales.' + 'SalesOrder%';

Kết quả:1 hàng hiển thị Sales.SalesOrderHeader truy vấn.

Bây giờ, nếu bất kỳ câu lệnh nào trong lô KHÔNG bao gồm OPTION (RECOMPILE) , kế hoạch có thể vẫn được lưu vào bộ nhớ cache, chỉ không thể sử dụng lại.

Hỏi:Bạn có thể sử dụng BETWEEN trong ví dụ ngày từ # 9 thay thế nếu> =và

A: Chà, BETWEEN không tương đương về mặt ngữ nghĩa với >= AND < , mà là >= AND <= và tối ưu hóa và thực hiện theo cùng một cách. Trong mọi trường hợp, tôi cố ý không sử dụng BETWEEN trên các truy vấn phạm vi ngày - từ trước đến nay - bởi vì không có cách nào để biến nó thành phạm vi mở. Với BETWEEN , cả hai đầu đều bao gồm và điều này có thể rất khó khăn tùy thuộc vào loại dữ liệu cơ bản (hiện tại hoặc do một số thay đổi trong tương lai mà bạn có thể không biết). Tiêu đề có vẻ hơi khắc nghiệt, nhưng tôi đi sâu vào chi tiết về điều này trong bài đăng blog sau:

GIỮA và ma quỷ có điểm gì chung?

Hỏi:Trong một con trỏ, "local fast_ntic" thực sự làm gì?

A: FAST_FORWARD thực sự là dạng rút gọn của READ_ONLYFORWARD_ONLY . Đây là những gì họ làm:

  • LOCAL làm cho nó sao cho phạm vi bên ngoài (theo mặc định con trỏ là GLOBAL trừ khi bạn đã thay đổi tùy chọn cấp phiên bản).
  • READ_ONLY làm cho nó để bạn không thể cập nhật con trỏ trực tiếp, ví dụ:sử dụng WHERE CURRENT OF .
  • FORWARD_ONLY ngăn khả năng cuộn, ví dụ:sử dụng FETCH PRIOR hoặc FETCH ABSOLUTE thay vì FETCH NEXT .

Việc đặt các tùy chọn này, như tôi đã trình bày (và đã viết trên blog), có thể có tác động đáng kể đến hiệu suất. Rất hiếm khi tôi thấy các con trỏ trong quá trình sản xuất thực sự cần đi chệch khỏi tập hợp các tính năng này, nhưng dù sao thì chúng thường được viết để chấp nhận các giá trị mặc định đắt hơn nhiều.

Hỏi:con trỏ hay vòng lặp while hiệu quả hơn là gì?

A: WHILE vòng lặp có thể sẽ hiệu quả hơn một con trỏ tương đương với các tùy chọn mặc định, nhưng tôi nghi ngờ rằng bạn sẽ tìm thấy rất ít nếu có bất kỳ sự khác biệt nào nếu bạn sử dụng LOCAL FAST_FORWARD . Nói chung, một WHILE loop * là * một con trỏ mà không được gọi là con trỏ, và tôi đã thách thức một số đồng nghiệp được đánh giá cao chứng minh tôi sai vào năm ngoái. WHILE của họ các vòng lặp không hoạt động tốt.

Hỏi:Bạn không khuyến nghị tiền tố usp cho các thủ tục do người dùng lưu trữ, điều này có tác động tiêu cực tương tự không?

A: A usp_ tiền tố (hoặc bất kỳ tiền tố nào khác ngoài sp_ hoặc không có tiền tố cho vấn đề đó) không * không * có tác động tương tự như tôi đã trình bày. Mặc dù vậy, tôi thấy rất ít giá trị khi sử dụng tiền tố trên các thủ tục được lưu trữ vì rất hiếm khi có bất kỳ nghi ngờ nào khi tôi tìm thấy mã cho biết EXEC something , rằng một cái gì đó là một thủ tục được lưu trữ - vì vậy có rất ít giá trị ở đó (không giống như, giả sử, các dạng xem tiền tố để phân biệt chúng với các bảng, vì chúng có thể được sử dụng thay thế cho nhau). Việc đặt cho mọi thủ tục cùng một tiền tố cũng làm cho việc tìm đối tượng bạn đang theo dõi trở nên khó khăn hơn nhiều, chẳng hạn như Object Explorer. Hãy tưởng tượng nếu mọi họ trong danh bạ điện thoại đều có tiền tố là LastName_ - điều đó giúp được gì cho bạn?

Hỏi:Có cách nào để dọn dẹp các kế hoạch đã lưu trong bộ nhớ cache khi có nhiều bản sao không?

A: Đúng! Chà, nếu bạn đang sử dụng SQL Server 2008 trở lên. Khi bạn đã xác định được hai gói giống hệt nhau, chúng sẽ vẫn có plan_handle riêng biệt các giá trị. Vì vậy, hãy xác định cái mà bạn * không * muốn giữ lại, sao chép plan_handle của nó và đặt nó bên trong DBCC này lệnh:

DBCC FREEPROCCACHE(0x06.....);
Hỏi:Việc sử dụng if else vv trong chương trình có gây ra kế hoạch xấu không, nó có được tối ưu hóa cho lần chạy đầu tiên và chỉ tối ưu hóa cho đường dẫn đó không? Vì vậy, các phần mã trong mỗi IF có cần được lập thành các thủ tục riêng biệt không?

A: Vì SQL Server hiện có thể thực hiện tối ưu hóa cấp câu lệnh, điều này ngày nay có ảnh hưởng ít nghiêm trọng hơn so với các phiên bản cũ hơn, trong đó toàn bộ quy trình phải được biên dịch lại thành một đơn vị.

Hỏi:Đôi khi tôi thấy rằng viết sql động có thể tốt hơn vì nó giúp loại bỏ vấn đề đánh hơi tham số cho sp. Điều này có đúng không? Có sự đánh đổi hoặc cân nhắc nào khác cần thực hiện đối với tình huống này không?

A: Có, SQL động thường có thể cản trở việc dò tìm tham số, đặc biệt trong trường hợp truy vấn "bồn rửa nhà bếp" lớn có rất nhiều tham số tùy chọn. Tôi đã xem xét một số vấn đề khác trong các câu hỏi ở trên.

Hỏi:Nếu tôi có một cột được tính toán trên bảng của mình là DATEPART (cột của tôi, năm) và trong chỉ mục trên đó, thì máy chủ SQL có sử dụng cột này với một SEEK không?

A: Nó nên, nhưng tất nhiên nó phụ thuộc vào truy vấn. Chỉ mục có thể không phù hợp để che các cột đầu ra hoặc đáp ứng các bộ lọc khác và thông số bạn sử dụng có thể không đủ chọn lọc để xác minh cho một tìm kiếm.

Hỏi:một kế hoạch có được tạo cho MỌI truy vấn không? Một kế hoạch có được tạo ngay cả cho những kế hoạch tầm thường không?

A: Theo những gì tôi biết, một kế hoạch được tạo cho mọi truy vấn hợp lệ, ngay cả những kế hoạch tầm thường, trừ khi có lỗi khiến kế hoạch không được tạo (điều này có thể xảy ra trong nhiều trường hợp, chẳng hạn như gợi ý không hợp lệ). Việc chúng có được lưu vào bộ nhớ đệm hay không (và thời gian chúng ở trong bộ nhớ đệm) phụ thuộc vào nhiều yếu tố khác, một số yếu tố tôi đã thảo luận ở trên.

Hỏi:Lệnh gọi sp_executesql có tạo (và sử dụng lại) kế hoạch đã lưu trong bộ nhớ cache không?

A: Có, nếu bạn gửi cùng một văn bản truy vấn, không thực sự quan trọng nếu bạn phát hành trực tiếp hay gửi qua sp_executesql , SQL Server sẽ lưu vào bộ nhớ cache và sử dụng lại gói.

H:Có thể thực thi một quy tắc (đối với môi trường nhà phát triển) nơi tất cả các máy nhà phát triển sử dụng khởi tạo tệp tức thì không?

A: Tôi không thấy lý do tại sao không. Mối quan tâm duy nhất của tôi là với việc khởi tạo tệp ngay lập tức, các nhà phát triển có thể không nhận thấy số lượng lớn các sự kiện tự động duyệt, điều này có thể phản ánh cài đặt tự động duyệt kém có thể có tác động rất khác đến môi trường sản xuất (đặc biệt nếu bất kỳ máy chủ nào trong số đó * không * đã bật IFI).

Hỏi:Với hàm trong mệnh đề CHỌN, liệu có đúng khi nói rằng tốt hơn là nên trùng lặp mã không?

A: Cá nhân, tôi sẽ nói có. Tôi đã nhận được rất nhiều hiệu suất khi thay thế các hàm vô hướng trong SELECT danh sách tương đương nội tuyến, ngay cả trong trường hợp tôi phải lặp lại mã đó. Tuy nhiên, như đã đề cập ở trên, trong một số trường hợp, việc thay thế hàm đó bằng một hàm có giá trị bảng nội tuyến có thể cho phép bạn sử dụng lại mã mà không bị phạt về hiệu suất khó chịu.

Hỏi:Chúng ta có thể sử dụng trình tạo dữ liệu để có cùng kích thước dữ liệu cho mục đích phát triển thay vì sử dụng dữ liệu sản xuất (khó lấy) không? Độ lệch dữ liệu có quan trọng đối với các kế hoạch đã đạt được không?

A: Độ lệch dữ liệu có thể có một yếu tố và tôi nghi ngờ điều đó phụ thuộc vào loại dữ liệu bạn đang tạo / mô phỏng và độ lệch có thể xảy ra. Ví dụ, nếu bạn có một cột varchar (100) trong quá trình sản xuất thường dài 90 ký tự và quá trình tạo dữ liệu của bạn tạo ra dữ liệu trung bình là 50 (đó là những gì SQL Server sẽ giả định), bạn sẽ thấy tác động khác nhau nhiều đến số của các trang và tối ưu hóa, và có thể là các thử nghiệm không thực tế lắm.

Nhưng tôi thành thật mà nói:khía cạnh cụ thể này không phải là thứ mà tôi đã đầu tư nhiều thời gian vào, bởi vì tôi thường có thể bắt nạt theo cách của mình để lấy dữ liệu thực. :-)

Hỏi:Có phải tất cả các hàm được tạo bằng nhau khi kiểm tra hiệu suất truy vấn không? Nếu không, có danh sách các chức năng đã biết mà bạn nên tránh khi có thể không?

A: Không, không phải tất cả các chức năng đều được tạo ra như nhau về hiệu suất. Có ba loại hàm khác nhau mà chúng ta có thể tạo (bỏ qua các hàm CLR trong thời gian này):

  • Các hàm vô hướng đa câu lệnh
  • Các hàm có giá trị trong bảng nhiều câu lệnh
  • Các hàm có giá trị trong bảng nội tuyến
    Các hàm vô hướng nội tuyến được đề cập trong tài liệu này, nhưng chúng là một huyền thoại và đối với SQL Server Ít nhất là năm 2014, cũng có thể được đề cập cùng với Sasquatch và Quái vật hồ Loch Ness.

Nói chung, và tôi sẽ đặt nó trong phông chữ 80pt nếu có thể, các hàm có giá trị bảng nội tuyến là tốt và nên tránh các hàm khác khi có thể, vì chúng khó tối ưu hóa hơn nhiều.

Các hàm cũng có thể có các thuộc tính khác nhau ảnh hưởng đến hiệu suất của chúng, chẳng hạn như liệu chúng có xác định hay không và liệu chúng có bị ràng buộc với lược đồ hay không.

Đối với nhiều mẫu chức năng, chắc chắn bạn cần phải cân nhắc về hiệu suất và bạn cũng nên biết về mục Kết nối này nhằm mục đích giải quyết chúng.

Hỏi:Chúng tôi có thể tiếp tục chạy tổng mà không có con trỏ không?

A: Có, chúng tôi có thể; có một số phương pháp khác ngoài con trỏ (như được trình bày chi tiết trong bài đăng trên blog của tôi, Các phương pháp tốt nhất để chạy tổng - được cập nhật cho SQL Server 2012):

  • Truy vấn con trong danh sách CHỌN
  • CTE đệ quy
  • Tự tham gia
  • "Cập nhật kỳ quặc"
  • Chỉ SQL Server 2012+:SUM () OVER () (sử dụng mặc định / RANGE)
  • Chỉ dành cho SQL Server 2012+:SUM () OVER () (sử dụng ROWS)

Tùy chọn cuối cùng cho đến nay là cách tiếp cận tốt nhất nếu bạn đang sử dụng SQL Server 2012; nếu không, có những hạn chế đối với các tùy chọn không phải con trỏ khác thường sẽ làm cho con trỏ trở thành lựa chọn hấp dẫn hơn. Ví dụ:phương pháp cập nhật kỳ quặc là không có tài liệu và không được đảm bảo hoạt động theo thứ tự bạn mong đợi; CTE đệ quy yêu cầu không có lỗ hổng trong bất kỳ cơ chế tuần tự nào bạn đang sử dụng; và các phương pháp tiếp cận truy vấn con và tự tham gia đơn giản là không mở rộng quy mô.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách thêm vị trí xếp hạng vào hàng với DENSE_RANK () trong SQL

  2. Làm thế nào để tính toán tỷ lệ duy trì trong SQL?

  3. Cắt mỡ trong nhật ký giao dịch

  4. Lập kế hoạch năng lực sử dụng dữ liệu hiệu suất

  5. Hiểu các câu lệnh PIVOT, UNPIVOT và Đảo ngược PIVOT