Dimensione del database - MDF troppo grande?


10

Sto mantenendo un database SQL Server 2005 che ospita circa 2,9 TB di dati (2 x 1,45 TB - Ho uno schema RAW e uno schema ANALISI, quindi sostanzialmente due copie dei dati ingeriti). Il modello di recupero è SEMPLICE ed .ldfè a 6 GB.

Per qualunque motivo, .mdfè 7.5Tb. Ora, ci sono forse solo 2-3 colonne aggiuntive nelle tabelle ANALYSIS e non molte NVARCHAR(MAX)colonne che, da quello che io (potrei aver capito erroneamente - per favore correggimi se sbaglio) potrebbero causare un'allocazione aggiuntiva dello spazio. Questo dopo aver ridotto il database proprio ora - era a ~ 9Tb prima di quello. qualche idea?

E, per favore, fatemi sapere se avete ulteriori domande - Sono molto nuovo nell'amministrazione del database e negli sforzi di ottimizzazione (di solito non faccio questo lato del lavoro :)).

Grazie molto!

Andrija


Grazie Marc - in che modo posso spostare questa domanda lì o devo ripubblicare?

Saluti - come probabilmente puoi immaginare, sono nuovo qui :)

Risposte:


11

Nelle stime delle dimensioni, hai preso in considerazione la quantità di spazio occupata dagli indici? Inoltre, se hai campi di testo impostati come multi-byte ( N[VAR]CHARanziché [VAR]CHAR) e i file di input sono UTF-8 o semplici byte per carattere, ciò aumenterà i requisiti di archiviazione fino a un fattore due. Inoltre, ricorda che se hai una chiave / indice cluster su una tabella, la dimensione di questo influisce su tutti gli altri indici sulla tabella perché includono il valore della chiave cluster per ogni riga (quindi per dare un esempio estremo se una tabella ha un NCHAR (10 ) dove farebbe un INT e che è la tua chiave / indice cluster, non solo stai utilizzando altri 16 byte per riga nelle pagine di dati, ma sprechi anche 16 byte per riga in ogni altro indice di quella tabella ) .

Inoltre, alcuni spazi verranno allocati ma non utilizzati, sia perché il motore DB ha lasciato uno spazio allocato dopo le eliminazioni in modo che possa essere riutilizzato rapidamente per i nuovi dati in quella tabella o perché il modello di inserimenti ed eliminazioni ha lasciato solo molte pagine pieno.

Puoi eseguire:

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

per dare una rapida occhiata a quali tabelle occupano spazio.

Anche EXEC sp_spaceusedeseguito all'interno di quel DB restituirà due set di risultati. Il primo elenca lo spazio totale allocato nel filesystem per i file di dati e quanto non allocato, il secondo elenca la quantità di spazio allocato utilizzata per pagine di dati, pagine di indice o attualmente non utilizzata.

sp_spaceused restituirà anche lo spazio utilizzato da un determinato oggetto, quindi è possibile eseguire questo ciclo per creare una tabella per l'analisi:

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

Il codice sopra genererà tutte le dimensioni della tabella in un elenco, più una singola riga per i totali. Se necessario, è possibile utilizzare le varie viste di sistema (come sys.objectse sys.dm_db_partition_statsutilizzate nella prima query sopra, vedere http://technet.microsoft.com/en-us/library/ms177862.aspx per ulteriori dettagli) per ottenere maggiori dettagli come lo spazio utilizzato da ciascun indice.


Esistono tre classi di spazio inutilizzato in un file di dati:

  1. Ciò che non è assegnato a nulla (questo viene mostrato nel primo gruppo di risultati sp_spaceusedsenza alcun oggetto specificato)
  2. Ciò che è allocato a un oggetto (riservato) ma non attualmente utilizzato (questo viene mostrato nel conteggio "non utilizzato" sp_spaceusednell'output.
  3. Quello bloccato nelle pagine parzialmente utilizzate (questo sembrerà essere usato come tutto è allocato in blocchi di singole pagine, una pagina lunga 8.192 byte). Questo è più difficile da rilevare / calcolare. È dovuto a un mix di due fattori:
    • Pagine divise. Man mano che i dati vengono aggiunti, si finisce spesso con pagine vuote in parte (il motore di archiviazione potrebbe sempre normalizzare il contenuto della pagina, ma ciò sarebbe molto inefficiente), e poiché le righe vengono eliminate i contenuti della pagina non vengono impacchettati automaticamente (di nuovo potrebbero essere, ma il extra Il carico di I / O è generalmente tutt'altro che utile).
    • Il motore di archiviazione non dividerà una riga su più pagine (questo insieme alla dimensione della pagina da cui proviene il limite di 8.192 byte per riga). Se le tue righe hanno dimensioni fisse e occupano 1.100 byte ciascuna, "sprecherai" almeno 492 byte di ciascun blocco di dati assegnato a quella tabella (7 righe occupano 7.700 byte e un ottavo non si adatterà, quindi i restanti byte vinceranno ' essere usato). Più ampie sono le file, peggio può essere. Tabelle / indici con righe a lunghezza variabile (che sono molto più comuni di quelle a lunghezza completamente fissa) in genere sono migliori (ma sono meno facili da calcolare).
      Un altro avvertimento qui sono oggetti di grandi dimensioni ( TEXTcolonne,[N]VARCHAR(MAX) valori superiori a una determinata dimensione e così via) man mano che vengono posizionati fuori pagina, prendendo solo 8 byte nei dati della riga principale per contenere un puntatore ai dati altrove) in modo da poter interrompere il limite di 8.192 byte per riga.

tl; dr: stimare le dimensioni previste del database può essere molto più complicato di quanto non sia naturale supporre inizialmente.


David - grazie mille per la risposta dettagliata! Sto analizzando il db in questo momento e le risposte di te e Kenneth sono state di grande aiuto nella mia comprensione dei fattori che influenzano la dimensione del database. Mi preoccupo sempre dell'efficienza (sia per quanto riguarda l'ingestione che l'uso dei dati) e le informazioni che avete fornito sono state preziose!
Andrija_Bgd

6

Prova a eseguire sp_spaceusedsul tuo database. Ad esempio, restituisce:

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

Per eseguirlo sul USEdatabase, eseguire solo il database sp_spaceused.

Se mostra ancora una grande quantità di spazio inutilizzato, puoi provare di nuovo a ridurre. A volte trovo che ci vogliono più tentativi. Inoltre a volte trovo che funzioni meglio per ridurre il singolo file anziché il database nel suo insieme. Tuttavia, ciò che potresti scoprire è che hai 2,9 TB di dati e altri 4 + TB di indici, nel qual caso il 7,5 TB è abbastanza ragionevole. Se vuoi avere un'idea della quantità di spazio (dati e indice) di ogni tabella, puoi eseguire anche sp_spaceuseda livello di tabella. È possibile eseguirlo su tutte le tabelle del database utilizzando il comando seguente:

EXEC sp_msforeachtable 'EXEC sp_spaceused [?];'

Sebbene il giusto avvertimento sp_msforeachtable non è documentato, non è supportato ed è noto che manca le tabelle. D'altro canto, ho avuto una buona dose di fortuna con me stesso.

Detto questo, il tuo database DOVREBBE avere una certa percentuale di spazio libero a seconda della crescita prevista. Fondamentalmente vuoi assicurarti di avere spazio per un periodo di crescita compreso tra 6 mesi e un paio d'anni. Inoltre vorrai controllare le tue autogrowthimpostazioni per assicurarti che siano appropriate alla tua situazione. In particolare, date le dimensioni del database che NON si desidera utilizzare% autogrowth.


Grazie! Ho usato sp_spaceused e sembra che i dati effettivi occupino effettivamente la quantità di spazio indicata, per quanto strano possa sembrare a me data la dimensione effettiva dei file piatti che sono stati caricati ... Gli indici sono piccoli (I Hav ' non ne ho creati altri perché sarebbero stati più un ostacolo che un aiuto nel mio caso) quindi immagino che siano solo i tavoli reali ad essere grandi ... Grazie mille per il tuo aiuto!
Andrija_Bgd,

I database occupano più spazio dei file flat. Esiste un certo sovraccarico per le strutture di righe e tabelle e un certo spreco a causa della struttura della pagina.
Kenneth Fisher,

-1

Utilizzando SQL Management Studio, 1.Fare clic con il pulsante destro del mouse sul database, quindi 2. Fare clic su Attività-> Riduci -> File

Vedrai una finestra di dialogo che mostra: a. Spazio attualmente assegnato b. Spazio libero disponibile + (% libero)

Se la tua% gratuita è superiore al 50%, potresti considerare di ridurre il file. Ho visto questo successo fino al 90%. Se decido di ridurre il file, di solito lo imposto a 2 o 3 concerti in più rispetto allo spazio allocato corrente. La maggior parte dei miei database ha meno di 50 grammi. Quindi, se hai un file molto più grande, potresti renderlo grande di 10 concerti. Di solito mi preoccupo di restringere solo se ho intenzione di spostare il database su un altro server, puoi leggere tutto su come ridurre i problemi su qualsiasi pagina sql.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.