Kích thước cơ sở dữ liệu - MDF quá lớn?


10

Tôi đang duy trì cơ sở dữ liệu SQL Server 2005 lưu trữ khoảng 2,9Tb dữ liệu (2 x 1,45Tb - Tôi có một lược đồ RAW và lược đồ ANALYSIS nên về cơ bản là hai bản sao của dữ liệu được nhập vào). Các mô hình phục hồi là ĐƠN GIẢN và .ldflà 6Gb.

Vì lý do gì, .mdflà 7,5Tb. Bây giờ, chỉ có khoảng 2-3 cột bổ sung trong các bảng PHÂN TÍCH và không có nhiều NVARCHAR(MAX)cột, từ những gì tôi (có thể hiểu nhầm - vui lòng sửa cho tôi nếu tôi sai) có thể gây ra sự phân bổ không gian bổ sung. Đó là sau khi thu hẹp cơ sở dữ liệu ngay bây giờ - nó đã ở mức ~ 9Tb trước đó. Có suy nghĩ gì không?

Và, xin vui lòng, cho tôi biết nếu bạn có thêm câu hỏi - Tôi rất mới đối với các nỗ lực quản trị cơ sở dữ liệu và tối ưu hóa (tôi thường không làm công việc này :)).

Cảm ơn nhiều!

Hà Lan


Cảm ơn Marc - bất kỳ cách nào tôi có thể chuyển câu hỏi này đến đó hoặc tôi cần phải đăng lại?

Chúc mừng - như bạn có thể đoán, tôi mới ở đây :)

Câu trả lời:


11

Trong ước tính kích thước của bạn, bạn đã tính đến dung lượng của các chỉ mục chưa? Ngoài ra, nếu bạn có các trường văn bản được đặt là nhiều byte ( N[VAR]CHARchứ không phải [VAR]CHAR) và các tệp đầu vào là UTF-8 hoặc một byte cho mỗi ký tự thì điều đó sẽ đẩy yêu cầu lưu trữ của bạn lên đến hai nhân tố. Hơn nữa, hãy nhớ rằng nếu bạn có một khóa / chỉ mục được nhóm trên một bảng thì kích thước của nó sẽ ảnh hưởng đến tất cả các chỉ mục khác trên bảng vì chúng bao gồm giá trị khóa được phân cụm cho mỗi hàng (vì vậy hãy đưa ra một ví dụ cực đoan nếu một bảng có NCHAR (10 ) trong đó một INT sẽ làm và đó là khóa / chỉ mục được nhóm của bạn, bạn không chỉ sử dụng thêm 16 byte mỗi hàng trong các trang dữ liệu mà bạn còn lãng phí 16 byte mỗi hàng trong mỗi chỉ mục khác trên bảng đó ) .

Ngoài ra, một số không gian sẽ được phân bổ nhưng không được sử dụng, vì công cụ DB đã để lại một số không gian được phân bổ sau khi xóa để có thể sử dụng lại nhanh chóng cho dữ liệu mới trong bảng đó hoặc do mẫu chèn và xóa chỉ còn lại một số trang đầy.

Bạn có thể chạy:

SELECT o.name
     , SUM(ps.reserved_page_count)/128.0 AS ReservedMB
     , SUM(ps.used_page_count)/128.0 AS UsedMB
     , SUM(ps.reserved_page_count-ps.used_page_count)/128.0 AS DiffMB
FROM sys.objects o  
JOIN sys.dm_db_partition_stats ps ON o.object_id = ps.object_id  
WHERE OBJECTPROPERTYEX(o.object_id, 'IsMSShipped') = 0  
GROUP BY o.name  
ORDER BY SUM(ps.reserved_page_count) DESC

để có được một cái nhìn nhanh chóng về những gì bảng đang chiếm không gian.

Cũng EXEC sp_spaceusedchạy trong DB đó sẽ trả về hai tập kết quả. Cái đầu tiên liệt kê tổng dung lượng được phân bổ trong hệ thống tệp cho các tệp dữ liệu và bao nhiêu phần không được phân bổ, phần thứ hai liệt kê bao nhiêu không gian được phân bổ được sử dụng cho các trang dữ liệu, cho các trang chỉ mục hoặc hiện không được sử dụng.

sp_spaceused cũng sẽ trả về không gian được sử dụng bởi một đối tượng nhất định, vì vậy bạn có thể lặp vòng này để xây dựng bảng để phân tích:

-- TEMP TABLES FOR ANALYSIS
CREATE TABLE #tTables (sName NVARCHAR(MAX), iRows BIGINT, iReservedKB BIGINT, iDataKB BIGINT, iIndexKB BIGINT, iUnusedKB BIGINT)
CREATE TABLE #tTmp (sName NVARCHAR(MAX), iRows BIGINT, sReservedKB NVARCHAR(MAX), sDataKB NVARCHAR(MAX), sIndexKB NVARCHAR(MAX), sUnusedKB NVARCHAR(MAX))
-- COLLECT SPACE USE PER TABLE
EXEC sp_msforeachtable 'INSERT #tTmp EXEC sp_spaceused [?];'
-- CONVERT NUMBER-AS-TEXT COLUMNS TO NUMBER TYPES FOR EASIER ANALYSIS
INSERT #tTables SELECT sName, iRows
                     , CAST(REPLACE(sReservedKB, ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sDataKB    , ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sIndexKB   , ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sUnusedKB  , ' KB', '') AS BIGINT) 
                FROM #tTmp
DROP TABLE #tTmp 
-- DO SOME ANALYSIS 
SELECT sName='TOTALS', iRows=SUM(iRows), iReservedKB=SUM(iReservedKB), iDataKB=SUM(iDataKB),  iIndexKB=SUM(iIndexKB), iUnusedKB=SUM(iUnusedKB) FROM #tTables ORDER BY sName
SELECT * FROM #tTables ORDER BY iReservedKB DESC
-- CLEAN UP
DROP TABLE #tTables

Đoạn mã trên sẽ xuất ra tất cả các kích thước bảng trong một danh sách, cộng với một hàng cho tổng số. Nếu cần, bạn có thể sử dụng các chế độ xem hệ thống khác nhau (thích sys.objectssys.dm_db_partition_statsđược sử dụng trong truy vấn đầu tiên ở trên, xem http://technet.microsoft.com/en-us/l Library / ms177862.aspx để biết thêm chi tiết) để biết thêm chi tiết như không gian được sử dụng bởi mỗi chỉ số.


Có ba lớp không gian chưa sử dụng trong một tệp dữ liệu:

  1. Cái không được phân bổ cho bất cứ thứ gì (điều này hiển thị trong tập kết quả đầu tiên từ sp_spaceusedkhông có đối tượng được chỉ định)
  2. Cái được phân bổ cho một đối tượng (dành riêng) nhưng hiện không được sử dụng (điều này thể hiện trong số lượng "không sử dụng" trong sp_spaceusedđầu ra.
  3. Điều đó bị khóa trong các trang được sử dụng một phần (điều này sẽ được sử dụng vì mọi thứ được phân bổ trong các đoạn trang đơn, một trang dài 8.192 byte). Điều này khó phát hiện / tính toán hơn. Đó là do sự kết hợp của hai yếu tố:
    • Chia trang. Khi dữ liệu được thêm vào, bạn thường kết thúc với một phần trang trống (công cụ lưu trữ luôn có thể bình thường hóa nội dung trang, nhưng điều này sẽ rất không hiệu quả) và vì các hàng bị xóa nên nội dung trang không được tự động đóng gói (có thể là một lần nữa Tải I / O thường không có giá trị).
    • Công cụ lưu trữ sẽ không phân chia một hàng trên nhiều trang (điều này cùng với kích thước trang có giới hạn 8.192 byte trên mỗi hàng xuất phát). Nếu các hàng của bạn có kích thước cố định và lấy 1.100 byte mỗi hàng thì bạn sẽ "lãng phí" ít nhất 492 byte của mỗi khối dữ liệu được phân bổ cho bảng đó (7 hàng mất 7,700 byte và 8 byte sẽ không phù hợp để các byte còn lại giành được ' t được sử dụng). Các hàng càng rộng, điều này có thể tồi tệ hơn. Các bảng / chỉ mục có các hàng có chiều dài thay đổi (phổ biến hơn nhiều so với các chiều dài cố định hoàn toàn) thường công bằng hơn (nhưng ít dễ dàng hơn để tính toán vấn đề).
      Một cảnh báo khác ở đây là các đối tượng lớn ( TEXTcột,[N]VARCHAR(MAX) các giá trị trên một kích thước nhất định, v.v.) khi chúng được đặt ngoài trang, chỉ cần lấy 8 byte trong dữ liệu hàng chính để giữ một con trỏ tới dữ liệu ở nơi khác) để có thể phá vỡ giới hạn 8.192 byte mỗi hàng.

tl; dr: Ước tính kích thước cơ sở dữ liệu dự kiến ​​có thể liên quan nhiều hơn so với giả định ban đầu.


David - cảm ơn bạn rất nhiều vì đã trả lời chi tiết! Tôi đang phân tích db ngay bây giờ và cả phản hồi của bạn và của Kenneth đã giúp ích rất nhiều cho sự hiểu biết của tôi về các yếu tố ảnh hưởng đến kích thước cơ sở dữ liệu. Tôi luôn quan tâm đến hiệu quả (cả khi nói đến việc nhập dữ liệu và sử dụng dữ liệu) và thông tin mà các bạn đã cung cấp là vô giá!
Andrija_Bgd

6

Hãy thử chạy sp_spaceusedtrên cơ sở dữ liệu của bạn. Ví dụ, nó trả về:

reserved           data               index_size         unused
------------------ ------------------ ------------------ ------------------
6032 KB            2624 KB            1664 KB            1744 KB

Để chạy nó trên cơ sở dữ liệu chỉ cần USEcơ sở dữ liệu sau đó chạy sp_spaceused.

Nếu nó vẫn hiển thị rất nhiều không gian chưa sử dụng, bạn có thể thử thu nhỏ lại. Đôi khi tôi thấy rằng phải mất nhiều lần thử. Ngoài ra đôi khi tôi thấy nó hoạt động tốt nhất để thu nhỏ tệp riêng lẻ thay vì toàn bộ cơ sở dữ liệu. Tuy nhiên, những gì bạn có thể tìm thấy là bạn có 2.9Tb dữ liệu và 4 + Tb chỉ mục khác trong trường hợp 7.5TB là khá hợp lý. Nếu bạn muốn cảm nhận về dung lượng (dữ liệu & chỉ mục) của mỗi bảng thì bạn cũng có thể chạy sp_spaceusedở cấp độ bảng. Bạn có thể chạy nó trên tất cả các bảng trong cơ sở dữ liệu bằng cách sử dụng lệnh sau:

EXEC sp_msforeachtable 'EXEC sp_spaceused [?];'

Mặc dù cảnh báo công bằng sp_msforeachtable không có giấy tờ, không được hỗ trợ và được biết là bỏ lỡ các bảng. Mặt khác, bản thân tôi đã có một số lượng lớn may mắn.

Tất cả điều đó được nói rằng cơ sở dữ liệu của bạn NÊN có một tỷ lệ không gian trống nhất định tùy thuộc vào sự tăng trưởng dự kiến ​​của bạn. Về cơ bản, bạn muốn đảm bảo rằng bạn có không gian cho bất kỳ nơi nào từ 6 tháng đến một vài năm tăng trưởng. Ngoài ra, bạn sẽ muốn kiểm tra autogrowthcài đặt của mình để đảm bảo chúng phù hợp với tình huống của bạn. Đặc biệt với kích thước của cơ sở dữ liệu của bạn, bạn KHÔNG muốn sử dụng% autogrowth.


Cảm ơn bạn! Tôi đã sử dụng sp_spaceuse và có vẻ như dữ liệu thực tế thực tế chiếm dung lượng được chỉ định, kỳ lạ như âm thanh của tôi với kích thước thực tế của các tệp phẳng được tải ... Chỉ số nhỏ Tôi đã tạo thêm bất kỳ cái nào vì chúng sẽ gây trở ngại nhiều hơn là giúp đỡ trong trường hợp của tôi) vì vậy tôi đoán đó chỉ là những cái bàn thực sự lớn ... Cảm ơn một triệu vì sự giúp đỡ của bạn!
Andrija_Bgd

Cơ sở dữ liệu chiếm nhiều không gian hơn các tệp phẳng. Có một lượng chi phí nhất định cho các cấu trúc hàng và bảng và một lượng chất thải nhất định do cấu trúc trang.
Kenneth Fisher

-1

Sử dụng SQL Management Studio, 1.Right Nhấp vào Cơ sở dữ liệu Sau đó 2. Nhấp vào Nhiệm vụ-> Thu nhỏ -> Tệp

Bạn sẽ thấy một hộp thoại hiển thị: a. Hiện tại phân bổ không gian b. Dung lượng trống miễn phí + (% miễn phí)

Nếu% Free của bạn trên 50%, bạn có thể xem xét thu nhỏ tệp. Tôi đã thấy hit này tới 90%. Nếu tôi quyết định thu nhỏ tệp, tôi thường đặt nó nhiều hơn 2 hoặc 3 hợp đồng so với không gian được phân bổ hiện tại. Hầu hết các cơ sở dữ liệu của tôi là ít hơn 50gigs. Vì vậy, nếu bạn có một tệp lớn hơn nhiều thì bạn có thể làm cho nó lớn hơn 10 hợp đồng. Tôi thường chỉ lo lắng về việc thu hẹp nếu tôi sẽ chuyển cơ sở dữ liệu sang một máy chủ khác, bạn có thể đọc tất cả về các vấn đề thu nhỏ trên bất kỳ trang sql nào.

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.