Spara databasplats för att öka prestanda
Förord
Det är lätt att sluta oroa sig över att man måste spara plats på hårddisken, då storlekarna på hårddiskarna bara fortsätter att växa sig större och priserna på dem går ner. Men genom att spara några bytes här och några bytes där så kan det hjälpa till att förbättra SQL Serverns prestanda betydligt. Om du någonsin har tittat på en exekveringsplan för en SQL-sats i SQL Server (och om du inte har det, gör det!) så kan du se att SQL Server genererar en ungefärlig ”kostnad” för att köra SQL-satsen. Kostnaden räknas uppenbarligen inte ut i pengar, utan i hur mycket resurser som krävs av datorn för att köra satsen. Den huvudsakliga komponenten inräknat i kostnaden är disk I/O. Så det innebär att om vi kan minska disk I/O så kan vi minska kostnaden för att köra satsen, och därmed höja prestandan. I den här artikeln ska vi titta lite på hur vi kan göra det.Innehåll
»»
»
»
»
Spara databasplats för ökad SQL Server prestanda
av Neil Boyle
Grunderna
Här följer ett relativt extremt exempel. Jag skapade två tabeller i SQL Server 7.0 och laddade var och en av dem med 10 000 4-byte strängar.
CREATE TABLE t1 (c1 CHAR(255) NOT NULL)
CREATE TABLE t2 (c1 VARCHAR(255) NULL)
En av tabellerna skapades med hjälp av VARCHAR(255) kolumn typen och den andra med CHAR(255) typen. Typen CHAR(255) använder sig av en fixerad längd för att lagra data, så om inte strängen fyller upp alla 255 möjliga tecken så är resterande längd slöseri på plats. Så är det dock inte med VARCHAR typen.
Genom att köra DBCC SHOWCONTIG mot tabellerna så visar den att i tabellen där jag lagrade 10 000 poster med CHAR (fixerad längd) så tar kolumnerna upp 334 sidor (i SQL 7.0 och SQL 2000 är en sida 8 kB) i diskutrymme. I tabellen som jag använde VARCHAR till så tog kolumnerna upp 23 sidor för att lagra samma data. Det reducerade diskutrymmet leder till att det går mycket snabbare att köra operationer som t ex ”SELECT COUNT(1) FROM…” mot den mindre tabellen.
Trots att exemplet ovan faktiskt var ganska extremt, så kan man även se stora skillnader vid mindre lagringar. I exemplet nedan har jag skrivit om SQL-satserna som följer, och fyllt varje tabell med 10 000 poster. (För att hålla exemplen simpla, så använder jag mig endast utav en kolumn, men det samma gäller för tabeller med flera kolumner – det är längden på posterna som spelar roll).
CREATE TABLE t1 (c1 CHAR(4000))
CREATE TABLE t2 (c1 CHAR(4040))
När tabellen t1 fylldes med 10 000 poster, så tog den upp 5 000 sidor av diskutrymme. Längden på posterna i t2 är exakt 1 % längre, så man kan förvänta sig att den tabellen kräver 1 % diskutrymme än t1. Men faktum är att den tar upp dubbelt så många sidor som t1. Anledningen till det är att SQL Server 7.0 kan lagra upp till 8 060 bytes data per sida, så det finns mer än väl plats för två poster från t1 på en sida. När vi däremot förlänger postens längd till 4040 bytes, så får det bara plats med en post per sida, vilket i slutänden leder till att vi sitter där med dubbelt så många sidor. SQL Server insisterar på att alltid få in en post per sida, och skulle aldrig försöka spara plats genom att dela upp en post på två sidor.
Återigen så var kanske det här exemplet också lite extremt, men generellt sett så gäller följande:
Ju kortare en post är desto fler poster får det plats på en sida, och desto mindre blir din tabell
Resultatet är ännu mer märkbart i SQL Server 6.5, där den maximala längden på posterna ligger på dryga 2 000 bytes. Exemplen ovan passar även in i SQL Server 2000.
Tips på hur du sparar plats
Se över följande förslag om hur du kan spara plats:- Använd VARCHAR över CHAR, om inte dina poster kommer att lagras i en specifik längd, eller om posterna kommer att vara väldigt korta
- Om du använder Unicode double-datatypes, som t ex NCHAR eller NVARCHAR, så kommer det att ta upp dubbelt (Duh!) så mycket plats. Så försök att undvika dem om du inte verkligen behöver dem.
- Om du inte behöver de stora siffrorna, så bör du använda SMALLINT och TINYINT för att spara in en eller tre bytes i taget. Och använd INTEGER istället för FLOAT eller NUMERIC där det passar dig.
- Du kan spara in fyra bytes genom att använda SMALLDATETIME istället för DATETIME, om en noggrannhet till närmaste minut går bra.
- Undvik att använda GUID kolumner, så till vida att du inte verkligen behöver dem
Det här är bara ett fåtal exempel, och du borde lära känna alla datatyper i SQL Server för att sedan välja bland dem väldigt försiktigt. Du kanske väljer SMALLMONEY istället för MONEY, men dem värden som den kan hantera är jämförelsevis små, speciellt om du ska hantera valutor som japanska Yen eller italienska Lire. Om du väljer en datatyp som du med tiden eventuellt kommer att ”växa ifrån”, så kan det skapa fler problem än vad det är värt.
Överväg Indexering
Kom ihåg att dina Index också tar upp en massa plats, så om du vill höja prestandan så får du hålla dina Index små (skapa bara Index som du kommer att använda, använd smala kolumner, och om det är möjligt – undvik komplicerade Index).Läs in dig mer angående Fillfactor och Pad_Index alternativen av Index. Generellt sett så lämnar SQL Server ett blanksteg i sina Index för att tillåta fortsatta justeringar. Men om du sätter ett Index på en tabell som aldrig, eller sällan, genomgår förändringar, så kan du justera din Fill factor till att spara plats och höja prestanda.
För tabeller som däremot genomgår förändringar ofta, så är det viktigt att du genomför regelbundna tabell- och Indexövervakningar, för att hålla dina data kompakta och lättåtkomliga.
Andra fördelar
Att hålla dina data så kompakta som möjligt reducerar inte bara lagringsutrymmet på disken, utan det ger dig vissa andra fördelar också:- Du kan få in mer data i ditt cache RAM, vilket ökar andelen träffar i cachen och minskar I/O lasten ännu mer
- Mindre och snabbare backups
- Mindre trafik när du transporterar data över nätverket
- Snabbare JOINS (korta kolumner är lättare att jämför än långa)
Läs vidare
Alla av de ämnen som följer är väldokumenterade i SQL Server Books Online, och det finns även en Quick Guide att hämta från min hemsida.SQL Server datatyper
Beräknade lagringsutrymmen
Hur du väljer effektiva Index
Hur du läser SQL-satsernas exekveringsplan
Tabell- och Indexövervakning
0 Kommentarer