2016-08-10 1 views
1

私は約400万のメッセージエントリを持つmysqlテーブルを作成していますが、タイムスタンプに基づいて最新の50メッセージを選択しようとしています。Mysql単純な頻繁なクエリのソートインデックスのパフォーマンスを作成する

さらに、返されるメッセージは固定接頭辞で始まらないという要件があります。

問題は、単一のクエリが約25%のCPUを使用しており、最大1.5秒かかることです。クエリは複数のクライアントによって頻繁に実行され、8コアのdb-serverでパフォーマンスの問題が発生しています。多分問題は、それがすべてのエントリのプレフィックスがチェックするということであることを

+----------------------+----------+ 
| Status    | Duration | 
+----------------------+----------+ 
| starting    | 0.000044 | 
| checking permissions | 0.000004 | 
| Opening tables  | 0.000010 | 
| init     | 0.000019 | 
| System lock   | 0.000005 | 
| optimizing   | 0.000005 | 
| statistics   | 0.000007 | 
| preparing   | 0.000007 | 
| Sorting result  | 0.000002 | 
| executing   | 0.000002 | 
| Sending data   | 0.000006 | 
| Creating sort index | 0.788023 | 
| end     | 0.000009 | 
| query end   | 0.000003 | 
| closing tables  | 0.000009 | 
| freeing items  | 0.000012 | 
| cleaning up   | 0.000010 | 
+----------------------+----------+ 

は、私が最初に思ったが、プロファイリングの後:

SELECT * FROM largeTable 
WHERE msg NOT LIKE 'myPrefix%' 
ORDER BY timestamp DESC LIMIT 0, 50; 

は、私がここにクエリの結果だ、組み込みMySQLのプロファイラとプロファイリングを試してみました。

| Creating sort index | 0.788023 | 

犯人と思われます。だからORDER BY句? これをどのようにスピードアップできますか? これを修正するために作成できるインデックスはありますか? 新しいメッセージはおよそ数秒ごとに追加されますが、クエリは頻繁に発生します。

ありがとうございました!

編集:コメントありがとうございます、ここに必要な情報があります。

データベースは自分のコードで作成されているのではなく、一部の外部Pythonサービスによって作成されています。私はまだインデックスを追加していない。

出力についての説明:

id:1  
select_type:SIMPLE 
table:largeTable 
type:ALL  
possible_keys:NULL 
key: NULL 
key_len:NULL  
ref: NULL 
rows: 3492633 
Extra: Using where; Using filesort 

テーブルの構造:

CREATE TABLE `largeTable` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `timestamp` int(10) unsigned NOT NULL, 
    `client_id` int(11) unsigned NOT NULL, 
    `name` varchar(32) NOT NULL, 
    `msg` varchar(528) NOT NULL, 
    `target_id` int(11) unsigned DEFAULT NULL, 
    `target_name` varchar(32) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `client` (`client_id`) 
) ENGINE=MyISAM AUTO_INCREMENT=4013829 DEFAULT CHARSET=utf8 | 
+0

あなたの 'msg'カラムにインデックスがありますか?または任意のインデックス? – aynber

+0

情報がありません: 'EXPLAIN'の出力、' SHOW CREATE TABLE'の出力、エンジンとInnoDB設定が使用されている場合。いつものように、これは 'innod_buffer_pool_size'設定が不十分であることに起因するI/O問題の可能性が最も高いです。デフォルト値は '128mbです。 – Mjh

+0

'show create table largeTable'を発行して公開してください。 Btwコアカウントは無関係です。 mysql上のsmpは – Drew

答えて

1

EXPLAINCREATE TABLEあなたがWHERE句を最適化するためのインデックスを持っていないと言います。そしてそれはORDER BYの前に起こります。だから最初にインデックスを作成することに焦点を当てましょう。

ALTER TABLE largeTable 
    ADD INDEX(msg); 

しかし、それがために二つの動作しません。

`msg` varchar(528) NOT NULL, 
ENGINE=MyISAM 

あなたが528個の文字を必要ですか?それを255に下げることができれば、それはうまくいくでしょう。 (またはMyISAMの場合は341)

実行中のMySQLのバージョンは? 5.7では、528 + utf8をインデックスにすることができます。 5.6も同様に行うことができますが、可能にするためにはいくつかの手順を実行する必要があります。

関連する問題