ホームページ  >  記事  >  データベース  >  mysqlの最適化 (1) テーブルの最適化とカラムの型の選択

mysqlの最適化 (1) テーブルの最適化とカラムの型の選択

黄舟
黄舟オリジナル
2016-12-29 16:04:131268ブラウズ

テーブルの最適化:

1: 固定長と可変長の分離

たとえば、id int は 4 バイトを占め、char(4) は長さが 4 文字を占め、これも固定長です、
time は各単位を意味します値が占めるバイト数は固定です。

コアフィールドと一般的に使用されるフィールドは固定長として構築され、Varchar、
text、および blob などの可変長フィールドは、別のテーブルに配置するのに適しています。主キーとコア テーブルを関連付けます。

SQL 実行クエリはすべて定数であるため、非常に迅速にスキップされます

2: 共通フィールドと一般的ではないフィールドを分離する必要があります

Web サイトの特定のビジネスを分析する必要があります。クエリ シナリオでは、クエリ頻度の低いフィールドが個別に分離されます

3: 相関統計が必要な 1 対多のフィールドに冗長なフィールドを追加します
相関クエリを削減します

次の BBS 効果を参照してください。投稿数の統計 カウントする代わりに、列の下に冗長なフィールドを追加します。これにより、記事の数が +1 ずつ更新されます。

列選択の原則:

。 1: フィールド型の優先順位 integer > date, time > enum,char>varchar > blob,text

列の特性分析: 整数型: 固定長、国/地域の区別なし、文字セットの違いなし

例: tinyint 1,2,3,4,5 71fb34173e4ee87dab1f85dc1c283a44 char(1) a、b、c、d、e、スペース的にはすべて 1 バイトを占有しますが、ソートによる順序付けでは前者の方が高速です

理由: 後者は文字セットを考慮する必要がある照合順序セット (つまりソート規則) を使用すると、

時間は固定長であり、処理が速く、スペースを節約できるため、タイムゾーンを考慮すると SQL を書くのが不便です。 where
> '2005-10-12'; 時刻は int 型で格納されます。
enum: を使用できます。ただし、値を制約する目的は、内部的に整数を使用することです。文字列と値の変換を実行する必要があります。文字セットと (ソート) 校正セットを考慮してください。Varchar、文字セットの変換とソートは遅くなります。 BLOB はメモリ一時テーブルを使用できません (並べ替えやその他の操作はディスク上でのみ実行できます)

性別: utf8 を例に挙げます

char(1)、3 文字 Long byte

enum('male',' Female' ); // 内部で数値に変換して保存します

tinyint(), // 0 1 2 // 1バイト固定長

SQL最適化本『MYSQL High Performance Optimization』について日付/時刻の選択では、マスターの明確な意見は、タイムスタンプを保存するために int unsgined not null を直接選択することです http://www.xaprb.com/blog/2014/01 /30/timestamps-in-mysql/

Time --->整数として保存

2: 十分です。寛大にしないでください (smallint、varchar(N) など)

理由: 大きなフィールドはメモリを無駄にし、速度に影響します。

age を例に挙げます、 tinyint unsigned not null、255 年前のものを保存できます。これで十分です。 int を使用すると 3 バイトが無駄になります

varchar(10) を使用すると、varchar(300) は同じ内容を保存しますが、テーブル内に結合クエリを実行すると、varchar( 300) はより多くのメモリを必要とします

3: NULL() の使用を避けるようにしてください

理由: NULL はインデックス作成に役立たないため、特殊なバイトでマークする必要があります。

ディスク上で占有されるスペースは実際にはより大きくなります (mysql5. 7 では null が改善されましたが、クエリは依然として不便です)

実験:

同じフィールドを持つ 2 つのテーブルを作成できます。1 つは null が許可され、もう 1 つは null は許可されません。それぞれに 10,000 が追加されます。インデックスファイルのサイズは、null インデックスの方が大きいことがわかります (mysql5.5 では、null が最適化され、サイズの違いは明らかではなくなりました)

さらに、null はクエリには不便です

。 where 列名 = null;

where 列名! = null; 値が見つかりません、

where 列名が null であるか、null ではない場合はクエリできます。


列挙型の説明

1 : enum 列は整数を使用して内部的に保存されます

2: enum 列は最速で enum 列に関連付けられます

3: enum 列は (var)char よりも弱いです--- char に関連付けられる場合、時間がかかります変換する時間がかかります。


4: 利点は、文字が非常に長い場合でも、列挙型は整数の固定長であることです。

クエリされるデータの量が増えると、列挙型の利点はより明白になります。

5 : enum は、変換速度が enum->enum、char->char、

よりも遅いため、char/varchar に関連していますが、データ量が特に多い場合にはこのように使用されることもあります ----- 、IO を節約できます。

テスト:


create table dictnn (
id int,
word varchar(14) not null default '',
key(word)
)engine myisam charset utf8;
create table dictyn (
id int,
word varchar(14),
key(word)
)engine myisam charset utf8;
alter table dictnn disable keys;
alter table dictyn disable keys;
insert into dictnn select id,if(id%2,word,'') from dict limit 10000;
insert into dictyn select id,if(id%2,word,null) from dict limit 10000;
rree
Column4bc407409327eef13c66a538ac7449a4Column

Time



Enumb6fe9feb9d4c7afa9e35009a988b8cc2enum

10.53




チャー

24.65




Enum4bc407409327eef13c66a538ac7449a4char

18.22




t2 テーブルの利点が明らかでない場合は、t3 の性別列、char(15)、を増やします。
char(20) ...

t3 性別列が大きくなるにつれて、t2 テーブルの利点が徐々に明らかになります。



その理由---- enum('manmaman で列挙される文字がどれだけ長くても','womenwomen') は、

内部 これらはすべて整数型で表され、メモリ内に生成されるデータのサイズは変わりません

ただし、char 型はメモリ内にさらに多くのデータを生成します



要約: enum と enum 型の関連付けが高速化されます

Enum 型は IO を節約します

上記は、mysql の最適化 (1) テーブルの最適化と列の型の選択の内容です。さらに関連する内容については、PHP 中国語 Web サイトに注目してください。 (www.php.cn)!




声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。