web-dev-qa-db-ja.com

MySQLほど高速ではないTokuDB

80.000.000行のMySQLデータベースをTokuDBに変換しました。

今私が実行すると:

 select count(id) from xxx where active=1

通常のMySQLリクエストの90%の時間がかかります。

より速く実行するために、さらに最適化する必要があるのは何ですか?


テーブル定義:

CREATE TABLE `adsDelivered` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `uid` varchar(40) NOT NULL,
  `_adsDelivered` bigint(20) NOT NULL DEFAULT '0',
  `_campaign` bigint(20) NOT NULL DEFAULT '0',
  `_ad` bigint(20) NOT NULL DEFAULT '0',
  `session` varchar(44) NOT NULL,
  `referer` text NOT NULL,
  `refererDomain` varchar(256) NOT NULL,
  `pageTime` int(11) NOT NULL DEFAULT '0',
  `pageVisibleTime` int(11) NOT NULL DEFAULT '0',
  `browser` varchar(256) NOT NULL,
  `ip` varchar(15) NOT NULL,
  `clicks` int(11) NOT NULL DEFAULT '0',
  `clickTimeLast` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `tag` varchar(256) NOT NULL,
  `countryShort` varchar(2) NOT NULL,
  `timeCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `timeUpdated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uid` (`uid`),
  KEY `_campaign` (`_campaign`),
  KEY `_ad` (`_ad`),
  KEY `_adsDelivered` (`_adsDelivered`),
  KEY `session` (`session`),
  KEY `tag` (`tag`),
  KEY `ip` (`ip`),
  KEY `countryShort` (`countryShort`),
  KEY `refererDomain` (`refererDomain`)
) ENGINE=TokuDB AUTO_INCREMENT=7420143 DEFAULT CHARSET=utf8;
6
Ploetzeneder

トクテックで働いています。ここでの答えはほとんどが良いです。ジャスティンが言うように、あなたは正しいインデックスを必要とし、あなたのスキーマはおそらく正しいインデックスを持っていません。 TokuDBがInnoDBよりも少し高速だったと聞いてうれしいですが、テーブルスキャンの場合、テーブルが古くないと仮定すると、どちらの方法でもかまいません。

これは私があなたが役立つと思うかもしれない索引付けについて与えた話です: http://www.youtube.com/watch?v=vaGAoK66ctM

前半はインデックス作成、後半はホワイトボード上のフラクタルツリーの技術的な説明です。うまくいけば、これがインデックスの設計に役立ちます。 TokuDBが提供するセカンダリインデックスのクラスタリングについて理解することを強くお勧めします。

他の点について。 RolandoMySQLDBAは、InnoDBとTokuDBのパフォーマンスに関してほぼ正しいです。ここでは、TokuDBのパフォーマンスについての考え方を説明します。データセットはメモリに収まりますが、TokuDBのフラクタルツリーには、InnoDBまたは他のBツリーベースのストレージエンジンに固有の利点はありません。ボトルネック、つまり崖は、データが大きく、メインメモリに収まらない場合に発生します。 InnoDBの書き込みパフォーマンス、および他のBツリーベースのストレージエンジンの書き込みパフォーマンスが低下した場合、TokuDBのパフォーマンスは一定のままです。これは、TokuDBから何かを取得していることを示しています。 TokuDBは、稼働中の既存のシステムを利用せず、そのパフォーマンスを大幅に向上させます。 TokuDBは、システムがメモリ内で適切に機能するようにしますが、メモリが不足すると故障し始め、データが増大してもシステムが適切に機能するようにします。それが、Perconaが示すベンチマークで起こっていること、つまり、iiBenchで起こっていることです( http://www.tokutek.com/resources/benchmarks/#iiBench )。

この書き込みパフォーマンスとTokuDBの圧縮を組み合わせると、インデックス付けの話で説明されているように、突然クラスタリングされたインデックスが比較的安価になります。より良いインデックスを維持することは、より安くなります。より適切なインデックスを使用すると、クエリからの多くのI/Oが消え、クエリのスループットが向上します。これがTokuDBのメリットです。

23

activeのインデックスがありません。このクエリでtonodbがInnoDBまたはMyISAMよりも高速である唯一の理由は、テーブル全体を調査しているため、テーブルに合計IOを削減する例外的な圧縮がある場合です。

テーブル内の行のごく一部(ギブオアテイクが30%未満)の値がactive = 1である場合、インデックスを追加すると役立ちます。

テーブルのほとんどの行がactive = 1であり、このクエリが重要な場合は、代わりにサマリーテーブルを維持することを検討してください。 Shard-Queryを使用して、テーブルのパーティション分割とパーティションへの並列アクセスを検討することもできます。

http://code.google.com/p/shard-query

TokuDBは、多くの一意でないインデックスを持つ大規模なテーブルのInnoDBと比較してINSERTIONSで高速ですが、必ずしもSELECTクエリでは高速ではありません。 FacebookのMark Callaghanは、Facebookグラフのベンチマークで、InnoDBと比較して、クエリパフォーマンスが3倍高速化し、ストレージフットプリントが50%減少しました。

データが追加のみの場合は、列ストアであるInfobright Community Edition、またはより学術的なFastbitを検討することもできます。

http://infobright.org

https://sdm.lbl.gov/fastbit/

7
Justin Swanhart

通常のmysqlリクエストの90%の時間がかかります。

時間がかからなければ、それはより速いですか?

TokuDBはSSDを効率的に使用すること、特に書き込みパフォーマンスと寿命を重視しています。ほとんどのデータがメモリに収まる場合、MyISAMとInnoDBはデータのフェッチがはるかに高速になります。また、シングルスレッドのベンチマークでは、これより速くなることはありません。あなたは、TokuDBが他のエンジンを大幅に上回っている状況を再現するための手順を何も講じておらず、遅くなるはずのシナリオの説明を求めているようです。

3
symcbean

Countクエリがeverであるとは思いません。== Tokuの強みを表しています。 1ショットでデータを挿入することも、絶えず更新されるインデックスを持つデータセットのテストの問題です。それがメモリに収まるかどうかに関係なく、インデックスは古くなっていないため、BTREEは適切で適切です。数週間待つと、BTREEはさらに断片化されます。フラクタルツリーは断片化されません。これがテストの1つの欠点です。また、何も選択していません。一度実行すると、複数のクラスター化インデックスが必要になる場合がありますが、InnoDBでは実行できません。 InnoDBでセカンダリインデックスが機能する方法は、私がそれについて最も嫌うものです。

InnoDBでは、インデックスが参照するすべての行でランダムな位置にあるポインターを本質的に逆参照(準自己結合)しているため、非プライマリインデックスを使用する2番目にヒットします。これを行うには、かなり大きな6バイトのキーを使用します。あなたがいたるところに跳ね回っているので、私はそれがハードウェアキャッシュに恐ろしいことをすることをかなり確信しています。

SELECTの対象に応じて、準結合が不要になるため、クラスター化インデックスの利点は非常に大きくなる可能性があります。

しかし、私は何を知っていますか? MyISAM +同時挿入を多くのものに使用することをやめます=)

@symcbeanそれはトク(SSD)の本来の意図だったと思いますが、最終的にはより大きな願望につながりました。それについてのプレスリリースを漠然と覚えています。

私はまた、MVCCがほとんどより複雑である読み取りが多い低競合環境を除いて、Tokuが読み取りに対して競争力があることを期待しています。また、クエリがパターンのないさまざまな列を非常にアドホックに参照している場合、複数のクラスター化インデックスはあまり効果がありません。 SELECTする必要のあるものの束をそれぞれが必要とする〜5の異なるタプルを参照する〜5タイプのクエリがある場合、複数のクラスター化インデックスのユーティリティを過小評価しないでください。特になし SSD、それは巨大です。局所性の原則について考えてください。 InnoDBセカンダリインデックスは、ディスクの回転に適していません。他の列を取得するために醜い準結合を行う必要がないので、カバリングインデックスを使用してハッキングできると思いますが、それはスケーリングされず、何もないために多くのものにインデックスを付けます(言う:たくさんのGB)、特に圧縮なし。インデックスのプレフィックスのみを参照しています。したがって、1〜2列の追加列でない限り、それはひどいスペースの乱用です。クラスター化インデックスでは、行は葉の単なるペイロードです。

それでもInnoDBが複数のクラスタリングインデックスをサポートできない理由はまだわかりません。それは適度なMyISAMでも役立ちます。クラスター化インデックスを常に模倣するためにカバーインデックスを悪用する人々がいますが、それは素晴らしいことです。

@Zardoshtそれがメモリに収まる場合でも、Tokuは時間の経過とともにBTREEよりもツリーのバランスを保ち、その場合でもより良いパフォーマンスを提供しませんか?

また、部分クラスタリングインデックスをTokuで実行できないのはなぜですか。しない場合はどうでしょう必要行全体?

2
Jaimie Sirovich

公平を期して、TokuDBにはInnoDBに対して長所と短所があります。

InnoDBのトランザクションスループットは、両方のストレージエンジンに同じレベルの競争条件であるデータ圧縮をもたらすボトルネックに到達するまで、TokuDBよりも優れています。

TokuDBは常にデータを圧縮し、InnoDBに比べて3倍のスペースを節約します。これを確認したのは 2つのストレージエンジンの間のPerconaベンチマーク でした。 InnoDBがディスク領域を使い果たしたため、テストを完了できませんでした。

テストでは、InnoDBのスループットは向上しましたが、低下し始めていました。時間の経過とともに十分なディスク容量があれば、真の評価に到達できます。私見、TokuDBはおそらく、スループット/ディスクスペースを単一のメトリックと見なすことで、長期的にはより良い結果をもたらすでしょう。

インデックスがある場合、セカンダリインデックスにはクラスター化インデックスへのROWIDエントリが含まれるため、ディスク領域の使用が遅くなる可能性があります。現在、TokuDBの内部構造を知らないため、TokuDBについて同じ主張をすることはできません。

2
RolandoMySQLDBA