2008-11-19 10 views
19

Wenn Sie in SqlServer 2005 eine Nachschlagetabelle (enum) entwerfen, sollten Sie, wenn Sie wissen, dass die Anzahl der Einträge niemals sehr hoch wird, anstelle von int auch tinyint verwenden? Ich bin sehr besorgt über die Leistung, insbesondere die Effizienz der Indizes.Lohnt es sich, Tinyint anstelle von Int für SqlServer-Lookup-Tabellen zu verwenden?

Angenommen, Sie haben diese Vertreter Tabellen:

Person 
------ 
PersonId int (PK) 
PersonTypeId tinyint (FK to PersonTypes) 

und

PersonTypes 
----------- 
PersonTypeId tinyint 
PersonTypeName varchar(50) 

Die offensichtlichen Faktoren sind Datengröße und Codierung Ärger. Wenn wir zu 100 Millionen Zeilen in der Personen-Tabelle kommen, speichern wir 300 Millionen weniger Bytes mit Tinyint im Gegensatz zu Int, plus den von unseren Indizes eingenommenen Platz. Keine große Menge an Daten, aber signifikant, wenn die Designentscheidung auf Dutzende großer Tabellen angewendet wird. Der Coding-Aufwand kommt natürlich von all diesen Casting-Problemen zurück im ASP.NET C#/VB-Code.

Wenn wir diese beiden Probleme beiseite legen, was kommt sonst noch ins Spiel? Werden Abfragen aufgrund der geringeren Größe der Indexseiten wesentlich effizienter? Oder gibt es eine Art Polsterung, die die Vorteile zunichte macht? Irgendwelche anderen gotchas?

Ich habe immer nur ints persönlich verwendet, aber ich denke an Tinyint für ein bevorstehendes Redesign/Migration auf einigen riesigen Tischen, also würde ich gerne einen Rat bekommen.

[Bearbeiten]

Nachdem mit diesem experimentieren rechnete der Codierung Ärger I erwies sich als ein Nicht-Thema. Der Wechsel von int zu tinyint hat zu keinerlei Problemen mit dem Casting geführt.

Antwort

17

Je schmaler eine Tabelle (oder Indexknoteneintrag) ist, desto mehr Datensätze (oder Indexknoten) können auf eine einzelne IO-Seite passen und desto weniger physische (und logische) Lese-IO-Operationen sind für jede Abfrage erforderlich. Je mehr Indexknoten sich auf einer einzelnen Seite befinden, desto weniger Ebenen gibt es möglicherweise im Index, von der Stamm- bis zur Blattebene, und wenn Sie eine Tabelle schmaler machen, überschreiten Sie den Schwellenwert, bei dem der Index eine Stufe kleiner sein kann kann eine dramatische Wirkung auf die Perforation haben.

Wenn Sie mit TinyInt Ihre Tabelle von 200 Byte Breite auf 197 Byte Breite ändern, wird es wahrscheinlich keinen Unterschied machen ... Aber wenn Sie es von 20 Byte auf 14 ändern (sagen Sie, Sie haben 2 Ints (dort), dann könnte es dramatisch sein ...

+0

Sowie ich abschätzen kann, wäre der Effekt 88 -> 70 für eine der wichtigsten Tabellen, die ich im Sinn habe. –

+0

wahrscheinlich nicht viel Bedeutung dann ... weiß nicht, welche db ur verwenden, aber auf SQL Server, IO-Seiten sind 8K, so für Tabellen Scans/sucht Sie von 93 bis 117 Datensätze pro Seite gehen würde. Was ist mit den Indizes? Sind diese int-Spalten in Ihren Indizes? Es könnte dort einen Biiger-Effekt haben. –

+0

Ja, die Tabelle hat mehr als ein Dutzend Indizes und wird stark für OLTP verwendet. Die Indexgröße auf der Festplatte beträgt 10x Datengröße. Diese Spalten stammen tatsächlich aus einer separaten Tabelle, die denormalisiert wird, um die Anzahl der benötigten Joins zu reduzieren. Indizes werden fast alle so modifiziert, dass sie diese neuen Felder enthalten. –

1

Ich bezweifle, dass die Verwendung von Smallint anstelle von Int wird viel Leistungsvorteil haben, außer in seltenen Fällen Rand. Sie können dafür jedoch problemlos eine Test-App erstellen, einige Testtabellen erstellen und eine Million Einfügungen/Aktualisierungen/Selektionen durchführen und die Leistung vergleichen.

2

Speicher 101: Kleineres Zeug bedeutet, dass man mehr im RAM hält und somit weniger Festplatten liest. Wenn die DB groß genug ist und Sie bestimmte Arten von Abfragen ausführen, könnte dies ein sehr schwerwiegender Faktor sein. Aber es wird wahrscheinlich keinen großen Unterschied machen.

+2

Mit Ausnahme der meisten Zeit wird alles, was kleiner als ein int ist, zu einem int im Speicher erweitert - und wenn dies nicht der Fall ist, wird das Element, das als nächstes kommt, so ausgerichtet, dass es die 2 Bytes verschwendet, die Sie sowieso speichern. –

1

Es gibt auch den Faktor der Aufrechterhaltung der Indizes/Disk-Backups/Tape-Backups, die auch Speicherplatz belegen, aber ich würde sagen, die wichtigste ist IO-und Speicher-Performance.

2

Irgendwelche anderen Fehler?

Ich bin mir nicht sicher, ob dies die Art von ist Sie bedeuten „Gotcha“, aber ich habe in Situationen führen, wo eine Datetime statt eine small gab falsches funktionales Verhalten verwenden, da die niedrigere Präzision small ‚didn t Vergleiche mit dem Datum mit der höheren Genauigkeit für zwei Daten, die ansonsten "gleich" sind.

Hier ist keine Chance, dass ein tinyint/smallint/int/bigint für denselben numerischen Integer-Wert identisch ist. Sie sind also sicher in dieser Hinsicht sicher, nicht, dass es Ihre Frage genau beantwortet.

Verwandte Themen