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

Khi nào tôi nên sử dụng biến bảng so với bảng tạm thời trong máy chủ sql?

Câu hỏi của bạn cho thấy bạn đã không mắc phải một số quan niệm sai lầm phổ biến xung quanh các biến bảng và bảng tạm thời.

Tôi đã viết một câu trả lời khá rộng rãi trên trang web DBA về sự khác biệt giữa hai loại đối tượng. Điều này cũng giải quyết câu hỏi của bạn về đĩa so với bộ nhớ (tôi không thấy bất kỳ sự khác biệt đáng kể nào về hành vi giữa hai loại).

Về câu hỏi trong tiêu đề là khi nào sử dụng biến bảng so với bảng tạm thời cục bộ, bạn không phải lúc nào cũng có lựa chọn. Ví dụ:trong các hàm, chỉ có thể sử dụng một biến bảng và nếu bạn cần ghi vào bảng trong phạm vi con thì chỉ có #temp bảng sẽ thực hiện (các tham số có giá trị bảng cho phép truy cập chỉ đọc).

Nếu bạn có lựa chọn, một số gợi ý dưới đây (mặc dù phương pháp đáng tin cậy nhất là chỉ cần kiểm tra cả hai với khối lượng công việc cụ thể của bạn).

  1. Nếu bạn cần một chỉ mục không thể được tạo trên một biến bảng thì tất nhiên bạn sẽ cần một #temporary bàn. Tuy nhiên, các chi tiết của điều này phụ thuộc vào phiên bản. Đối với SQL Server 2012 trở xuống, các chỉ mục duy nhất có thể được tạo trên các biến bảng được tạo ngầm thông qua UNIQUE hoặc PRIMARY KEY hạn chế. SQL Server 2014 đã giới thiệu cú pháp chỉ mục nội tuyến cho một tập hợp con các tùy chọn có sẵn trong CREATE INDEX . Điều này đã được mở rộng kể từ đó để cho phép các điều kiện chỉ mục được lọc. Các chỉ mục có INCLUDE Tuy nhiên, vẫn không thể tạo các cột -d hoặc chỉ mục columnstore trên các biến bảng.

  2. Nếu bạn liên tục thêm và xóa số lượng lớn các hàng khỏi bảng thì hãy sử dụng #temporary bàn. Điều đó hỗ trợ TRUNCATE (hiệu quả hơn DELETE cho các bảng lớn) và các lần chèn tiếp theo sau TRUNCATE có thể có hiệu suất tốt hơn những hiệu suất sau DELETE như minh họa ở đây.

  3. Nếu bạn sẽ xóa hoặc cập nhật một số lượng lớn các hàng thì bảng tạm thời có thể hoạt động tốt hơn nhiều so với một biến bảng - nếu nó có thể sử dụng chia sẻ tập hợp hàng (xem "Ảnh hưởng của chia sẻ tập hợp hàng" bên dưới để làm ví dụ) .
  4. Nếu kế hoạch tối ưu sử dụng bảng sẽ khác nhau tùy thuộc vào dữ liệu thì hãy sử dụng #temporary bàn. Điều đó hỗ trợ tạo thống kê cho phép kế hoạch được biên dịch lại động theo dữ liệu (mặc dù đối với các bảng tạm thời được lưu trong bộ nhớ cache trong các thủ tục được lưu trữ, hành vi biên dịch lại cần được hiểu riêng).
  5. Nếu kế hoạch tối ưu cho truy vấn sử dụng bảng không có khả năng thay đổi thì bạn có thể xem xét một biến bảng để bỏ qua chi phí tạo và biên dịch lại thống kê (có thể yêu cầu gợi ý để sửa kế hoạch bạn muốn).
  6. Nếu nguồn cho dữ liệu được chèn vào bảng là từ SELECT có thể đắt tiền sau đó, hãy xem xét rằng việc sử dụng một biến bảng sẽ chặn khả năng xảy ra điều này bằng cách sử dụng một kế hoạch song song.
  7. Nếu bạn cần dữ liệu trong bảng để tồn tại khi khôi phục một giao dịch người dùng bên ngoài thì hãy sử dụng một biến bảng. Một trường hợp sử dụng khả thi cho việc này có thể là ghi lại tiến trình của các bước khác nhau trong một lô SQL dài.
  8. Khi sử dụng #temp bảng trong khóa giao dịch người dùng có thể được giữ lâu hơn so với các biến bảng (có thể cho đến khi kết thúc giao dịch so với kết thúc câu lệnh phụ thuộc vào loại khóa và mức độ cách ly) và nó cũng có thể ngăn chặn việc cắt ngắn tempdb nhật ký giao dịch cho đến khi giao dịch của người dùng kết thúc. Vì vậy, điều này có thể ưu tiên việc sử dụng các biến bảng.
  9. Trong các quy trình được lưu trữ, cả biến bảng và bảng tạm thời đều có thể được lưu vào bộ nhớ đệm. Bảo trì siêu dữ liệu cho các biến bảng được lưu trong bộ nhớ cache ít hơn cho #temporary những cái bàn. Bob Ward chỉ ra trong tempdb của anh ấy trình bày rằng điều này có thể gây ra tranh cãi bổ sung trên các bảng hệ thống trong điều kiện đồng thời cao. Ngoài ra, khi xử lý số lượng dữ liệu nhỏ, điều này có thể tạo ra sự khác biệt có thể đo lường được đối với hiệu suất.

Ảnh hưởng của việc chia sẻ bộ hàng

DECLARE @T TABLE(id INT PRIMARY KEY, Flag BIT);

CREATE TABLE #T (id INT PRIMARY KEY, Flag BIT);

INSERT INTO @T 
output inserted.* into #T
SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY @@SPID), 0
FROM master..spt_values v1, master..spt_values v2

SET STATISTICS TIME ON

/*CPU time = 7016 ms,  elapsed time = 7860 ms.*/
UPDATE @T SET Flag=1;

/*CPU time = 6234 ms,  elapsed time = 7236 ms.*/
DELETE FROM @T

/* CPU time = 828 ms,  elapsed time = 1120 ms.*/
UPDATE #T SET Flag=1;

/*CPU time = 672 ms,  elapsed time = 980 ms.*/
DELETE FROM #T

DROP TABLE #T


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để thay đổi từ chế độ SQL Server Windows sang chế độ hỗn hợp (SQL Server 2008)?

  2. Giá trị hiệu suất của COMB guids

  3. Làm cách nào để thực thi một thủ tục được lưu trữ trong MS SQL Server trong java / jsp, trả về dữ liệu bảng?

  4. Kết nối với máy chủ SQL với xác thực Windows từ máy Linux thông qua JDBC

  5. LEN () trong SQL Server là gì?