2016-04-11 15 views
0

私はいつも成長している巨大なmysqlテーブルを持っています。チャットデータを記録しています。ユーザ名のクエリがそうでなければ5秒のように取ることができますので、私のテーブルには、ユーザー名をインデックス作成巨大なmysqlテーブルの最適化

CREATE TABLE `log` (
    `id` BIGINT(20) NOT NULL AUTO_INCREMENT, 
    `channel` VARCHAR(26) NOT NULL, 
    `timestamp` DATETIME NOT NULL, 
    `username` VARCHAR(25) NOT NULL, 
    `message` TEXT NOT NULL, 
    PRIMARY KEY (`id`), 
    INDEX `username` (`username`) 
) 
COLLATE='latin1_swedish_ci' 
ENGINE=InnoDB 
AUTO_INCREMENT=2582573 
; 

どのように見えるか

これはちょっと重要です。

このテーブルをさらに最適化して、膨大な量のデータを作成する準備ができましたか? 100m行も問題にならないようにします。

+0

このような場合は、リレーションDB以外のソリューションを検討することをおすすめします。 – Jacco

+0

ちょうど.txtファイル以外にどのような選択肢がありますか? – gempir

+1

このテーブルの最適なインデックスは実際に実行している実際のクエリによって異なります。たとえば、クエリで "ORDER BY t.timestamp DESC"や "WHERE t.timestamp> = NOW() - INTERVAL 4 DAY"などを指定すると、\ timestamp \のインデックスが有効になる場合があります。クエリでユーザー名に等価述語が含まれている場合は、シングルトンの「ユーザー名」列の索引の代わりに複合索引を「ONログ(ユーザー名、\ 'タイムスタンプ\')」にすることをお薦めします。また、* partitioning *は、巨大なテーブルの管理に役立つことがあります。 – spencer7593

答えて

1
`id` BIGINT(20) NOT NULL AUTO_INCREMENT, 

40億行以上ありますか?そうでない場合は、INT UNSIGNEDを使用して、1行につき4バイトを節約してください。セカンダリインデックスの各行に対してさらに4バイトを追加します。

`channel` VARCHAR(26) NOT NULL, 
`username` VARCHAR(25) NOT NULL, 

ノーマライズ各 - つまり、たとえば、によってSMALLINT UNSIGNEDこれを交換し、それらの間のマッピングを持っています。貯蓄:たくさん。

INDEX `username` (`username`) 

これはuser_idになり、さらに節約できます。

小さい - >よりキャッシュ可能 - >高速。

その他のクエリはありますか?

「メモリ使用量」 - InnoDBの場合、利用可能なRAMの約70%に「innodb_buffer_pool_size」を設定してください。それでは、何が記憶にあるのか、それが何ではないのか心配しましょう。テーブルが大きすぎてキャッシュできない場合は、データを縮小して(他のコメントで述べたように)「良い」インデックスを提供し、「参照の局所性」のテーブルを構成する必要があります。クエリ、私はこれに対処することはできません)。

あなたは文字列の代わりにIDを使用することについて不平を言いました...それを詳しく見てみましょう。別個のユーザー名はいくつありますか?チャンネル?データはどのように入力されますか?一度に1行またはバッチを取得しますか?何かが直接INSERTsをしているか、またはINSERTsを実行しているコードにフィードしていますか?正規化と挿入を行うにはSTORED PROCEDUREがありますか? 1秒間に何百行も挿入する必要がある場合は、両方を実行する方法について議論し、効率的に実行することができます。

あなたは約PARTITIONsを質問しませんでした。私はではないは簡単な質問usernameのためにそれをお勧めします。

2.5M行は約85パーセンタイルです。 100万行がよりエキサイティングです - 98パーセンタイル。

+0

データが来ます毎回1行で、ストアドプロシージャは確かに可能であり、良いでしょう。チャンネルとユーザー名は理論的には同じです。その合計は何ですか?推測するのは難しいですが、twitch.tvにはおそらく何百万というユーザーがいます。実際には最大で約50kチャンネルしか持たないでしょう。これはすでにとても役に立ちました。 – gempir

+0

2500Kのうち50K - 正規化のための良い候補のように聞こえる。 'MEDIUMINT UNSIGNED'(3バイト、16M制限)は、使用するintのサイズに似ています。 –

+0

大丈夫。ユーザー名とチャンネルにIDを使用すると仮定します。データを挿入するとき以外は、IDを取得できないため、IDとIDを保持する別のテーブルがあり、IDのインデックスも作成する必要があります。大きな表の中でチャンネルとユーザー名をインデックスします。それは実際には大きなテーブルに2つのvarchars(25)を保持するよりも効率的でしょうか?また、私はIDを得ることができないので、私はIDのusernameテーブルのすべてのメッセージのために余分な挿入を行う必要があります。チャンネルとユーザー名は基本的に同じbtwです。彼らは大きなテーブルで関係している – gempir

関連する問題