INTでTINYINTを使用する場合


91

一般に、私は常にIntsを使用します。ただし、データの保存が保証される最小のデータ型を使用する必要があるため、理論的にはこれがベストプラクティスではないことを知っています。

たとえば、tinyint保存するデータが1、0、またはnullのみであることがわかっている場合に使用することをお勧めします(2または3に拡張する可能性は非常に小さい)。

ただし、これを行うために知っている唯一の理由は、4バイトの代わりに1バイトを使用して、ストレージの目的のためです。

使用しての影響は何ですかtinyint(またはsmallintあるいはbigint単に上)intハードドライブの容量を節約する以外は、?


2
これは非常に良い質問(+1)です。MySQLにはSELECT ... PROCEDURE ANALYSE()があります。これは、指定されたSELECTに対してテーブルが持つべき最小のデータ型を実際に推奨します。それが私の答えの背後にあるインスピレーションの一部でした。
RolandoMySQLDBA

3
細かい質問ですが、正確にはtinyintの範囲は0〜255です。ビットフィールドは0または1(またはNULL)です。tinyintのストレージコストは1バイトです。テーブル内の8ビットフィールドごとに1バイトのストレージがかかります。msdn.microsoft.com/en-us/library/ms187745.aspxおよびmsdn.microsoft.com/en-us/library/ms177603.aspx
billinkc

@billinkcそうです。そのため、列を拡張して値2または3を含める可能性を述べたのは、2または3を含める場合は、tinyintを(非常に小さいスケールで)使用する必要があります。
リチャード

1
「たとえば、保存するデータが1、0、またはnullであることがわかっている場合は、tinyintを使用することをお勧めします(2または3に拡張する可能性は非常に小さい)。」そのようなことにはENUMを使用します。これらはビットフィールドとして格納され、他の多くの人が指摘しているように、レコードごとの小さな節約は、データベース全体で大きな節約になります-さらに列がイ​​ンデックス付けされている場合でも。

2
@ user6665 I'd use an ENUM for such a thing.SQL Serverにはありません。どんな種類の列挙も含まれていないため、そうしません。
underscore_d

回答:


92

ディスク容量は安いです...それはポイントではありません!

ストレージスペースの観点から考えるのではなく、代わりにバッファプールとストレージ帯域幅について考えてください。極端な場合、CPUキャッシュとメモリバス帯域幅。リンクされた記事は、クラスター化されたキーの選択が不適切な問題(INT vs GUID vsシーケンシャルGUID)を強調するシリーズの一部ですが、バイトがもたらす違いを強調しています。

優先メッセージは設計事項です。VLDBのテリトリーに到達するまで、適切に指定されたサーバー上の個々のデータベースに違いは現れませんが、数バイトを節約できる場合は、そうしないでください。

以前の質問で説明された環境を思い出します。SQLインスタンスごとにサイズが50MB〜50GBの400以上のデータベース。その環境全体でレコードごと、テーブルごと、データベースごとに数バイトをスクラブすると、大きな違いが生じる可能性があります。


29

他の答えに加えて...

行とインデックスエントリは8kページに保存されます。したがって、1行あたり3バイトの100万行はディスク上の3 MBではありません。ページあたりの行数(「ページ密度」)に影響します。

nvarcharからvarchar、smalldatetimeからdatetime、intからtinyintなどにも同じことが当てはまります。

編集、2013年6月

http://sqlblog.com/blogs/joe_chang/archive/2013/06/16/load-test-manifesto.aspx

この記事は述べています

重要な基準は、カーディナリティーとページ対行の比率です。

したがって、データ型の選択は重要です


5
いい視点ね。絶対的な最悪の例は、列を追加する完全に固定長の列で構成される4028バイトの行です。smallintを追加すると4030(ページごとに2行)になりますが、intは境界を越えてプッシュします(ページごとに1行、ページごとに4028バイトが無駄になります)。
マークストーリースミス

私はかつてint vs bigintでパフォーマンステストを行いました。100万件のレコードを保存し、時間とストレージを比較し、それらを1つずつ取得して、パフォーマンスを再度測定します。大きな違いは見られませんでした。int対tinyintに対して同じパフォーマンステストを実行します。アプリケーションの80%でこれを無視できると思うので、データタイプの一貫性が向上し、メンテナンスコストが削減されます。
サイードネアマティ

1
@SaeedNeamati マークの答えから記事を読み直した方がいいかもしれません(「聞いたことありますか。これ終わらせてください。後でパフォーマンスについて心配しますか?...いつも聞いています...」)、gbnはここにあります。。持ち帰りは、非効率的な選択が適切なスケールでストライプを表示することであり、OPの直感は間違っていないと思います。
ルフィン

14

考慮されるのはテーブルストレージだけではありません。int列が複合キーの一部であるインデックスを使用する場合は、インデックスページをできるだけいっぱいにする必要があります。これは、インデックスエントリが可能な限り小さいためです。

BTREEページのインデックスエントリを調べる方が、データ型が小さいほど少し速くなることは間違いなく期待できます。ただし、インデックスエントリに関係するVARCHARは、INTでTINYINTを使用することによるパフォーマンスの向上を相殺(無効化)します。

それにもかかわらず、インデックスエントリが複合エントリを持ち、すべてが整数である場合、整数が小さいほど、バイト単位で、より良く、より速くなります。


13

データベースが大きくなると、すべてが複雑になります。

  • メンテナンスウィンドウを拡大または再スケジュールする必要がある
  • バックアップ(1日の終わりの完全バックアップは不合理な時間を浪費するため、差分バックアップまたはログバックアップが必要であり、1週間に1回、場合によっては1か月に1回)
  • パフォーマンスの維持は時間を浪費するものになり(数百万行のテーブルでインデックスを作成するのは簡単な時間ではありません)、スケジュールが変更される必要があり、テーブルが広い場合は悪化します...
  • そして、100Gbのバックアップをネットワーク経由で送信することは、私がケーキと呼ぶものではありません-特に(何らかの理由で)ネットワークが75Gbマークで接続を切断することに頑固な場合...(私が作業していたインストールで起こったネットワーク上のマップされたドライブにバックアップしていました-ネットワーク)...

そして、それと関係するデータ型は何ですか?すべて。必要以上の行サイズを使用すると、行サイズがページに記録できるレコードが1つしかないような場合、データベースページが必要以上にいっぱいになるか、スペースを浪費します。その結果、書き込みおよび読み取りに必要なページが多くなり、それをキャッシュするためにより多くのRAMメモリが使用されます(より大きなレコードにはより大きなメモリが必要です)。また、データ型はディスクから必要以上に大きく指定されているため、インデックスには同じ問題が発生します-特に、作成された他のインデックスは定義で暗黙的にそのプライマリキーをコピーするため、その2つのBIGINT列のプライマリキーをクラスター化する場合。

テーブル内の数百万行の列、またはデータを格納するために4バイトの整数を必要としない数百万行にFKされる小さなテーブルさえあるが、2バイトの列がある場合、十分-使用SMALLINTを。0〜255の範囲の値で十分な場合、TINYINT。はい/いいえフラグ?BITがあります。


9

forとtinyintvs intには、ディスク容量、ページ分割、メンテナンス時間などの明確な違いがありますが、にはこれらはありませんvarchar

それでは、varchar(4000)とにかく必要なスペースだけを使い果たすので、すべてのテキストフィールドをとして宣言しないのはなぜですか?さらに、データが切り捨てられないことが保証されます。

答えはもちろんです:

  1. 意図の明確化(名前フィールドが4000文字である理由を誰も理解しないため)
  2. 誰も名前として伝記全体を入力しないようにするための検証。

これらのまったく同じ理由も当てはまりますtinyint


3
これは古いスレッドですが、明確化と検証だけが理由ではありません。VARCHAR(20)である必要があるものにVARCHAR(4000)がある場合、クエリプランは、メモリとCPUの要件がその列に関して本来あるべき数の倍数であると考えます。これを行う時間はありませんでしたが、おそらくVARCHAR(20)のクエリプランを見てからVARCHAR(4000)に変更し、推定コストを確認することでこれを見ることができると思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.