2009-09-18 73 views
15

私は現時点では控えめなサイズのテーブル277kレコードを持っています。これはFULLTEXTの検索を実行しようとしています。検索は送信データフェーズに達するまでは非常に高速です。MySQL「データを送信中」がひどく遅い

表:

CREATE TABLE `sqinquiries_inquiry` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `ts` datetime NOT NULL, 
    `names` longtext NOT NULL, 
    `emails` longtext NOT NULL, 
    PRIMARY KEY (`id`), 
    FULLTEXT KEY `sqinquiries_inquiry_search` (`names`,`emails`) 
) ENGINE=MyISAM AUTO_INCREMENT=305560 DEFAULT CHARSET=latin1 

問合せ:

SELECT * FROM `sqinquiries_inquiry` WHERE (
    MATCH (`sqinquiries_inquiry`.`names`) AGAINST ('smith' IN BOOLEAN MODE) OR 
    MATCH (`sqinquiries_inquiry`.`emails`) AGAINST ('smith' IN BOOLEAN MODE) 
) ORDER BY `sqinquiries_inquiry`.`id` DESC LIMIT 100 

プロフィール:(私は一見役に立たない情報を切り取ら)

+-------------------------+----------+ 
| Status     | Duration | 
+-------------------------+----------+ 
| preparing    | 0.000014 | 
| FULLTEXT initialization | 0.000015 | 
| executing    | 0.000004 | 
| Sorting result   | 0.000008 | 
| Sending data   | 2.247934 | 
| end      | 0.000011 | 
| query end    | 0.000003 | 
+-------------------------+----------+ 

DESCRIBEは偉大に見える、シンプルな1つのライナー: は説明:

id: 1 
select_type: SIMPLE 
table: sqinquiries_inquiry 
type: index 
possible_keys: NULL 
key: PRIMARY 
key_len: 4 
ref: NULL 
rows: 100 
Extra: Using where 

データを送信するの2.25秒はどこから来ているので、私は理解していないことはありますか?私はPythonとコンソールmysqlアプリで同様のパフォーマンスを見ています。どちらもlocalhostに接続しています。

アップデート:コメントパー

  • 平均行サイズを要求し、それは次のとおりです。コメントパー53.8485
  • 、ここでは上記DESCRIBEです。
+0

取得するデータの量はどれくらいですか?あなたがわからない場合は、テーブルの統計を見て、私たちに平均行サイズを教えてください。 – longneck

+0

平均行サイズを調べる方法がわからなかったので、これを上に出力しました: 'AVG(LENGTH(LENGTH(LENGTH)+ LENGTH(Eメール)+ LENGTH(LENGTH)+ LENGTH 〜からsqinquiries_inquiry'。より良い方法があれば教えてください。 –

+0

問題は、あなたの 'FULLTEXT KEY'が使用されていないことです。 'DESCRIBE'を投稿してください。 – Quassnoi

答えて

32

DESCRIBE、シンプルな1つのライナーを偉大に見えます。

クエリで1つのテーブルのみを使用しているため、1つのライナー以外は使用できません。

ただし、クエリではFULLTEXTインデックスは使用されません。インデックスが使用可能にするには

は、クエリを少し書き換える必要があります:あなたはインデックスが上で定義された列の正確なセットと照合する場合

SELECT * 
FROM sqinquiries_inquiry 
WHERE MATCH (names, emails) AGAINST ('smith' IN BOOLEAN MODE) 
ORDER BY 
     id DESC 
LIMIT 100 

MATCHはインデックスのみを使用しています。

DESCRIBEの末尾にidUsing index; Using whereのインデックススキャンが使用されます。

Sending dataはかなり誤解を招きます。これは、実際には、前の操作の終了から現在の操作の終了までの時間です。

SET profiling = 1; 

SELECT * 
FROM t_source 
WHERE id + 1 = 999999; 

SHOW PROFILE FOR QUERY 39; 

単一の行と、このプロファイル返さ:インデックスが使用できないため、MySQL完全なテーブルを実行する必要が

'starting', 0.000106 
'Opening tables', 0.000017 
'System lock', 0.000005 
'Table lock', 0.000014 
'init', 0.000033 
'optimizing', 0.000009 
'statistics', 0.000013 
'preparing', 0.000010 
'executing', 0.000003 
'Sending data', 0.126565 
'end', 0.000007 
'query end', 0.000004 
'freeing items', 0.000053 
'logging slow query', 0.000002 
'cleaning up', 0.000005 

を例えば

は、私はこのクエリを実行しましたスキャン。

0.126565秒は、実行の開始(最初の行が読み取られた時刻)から実行の終了(最後の行がクライアントに送信された時刻)までの時間です。

この最後の行はテーブルの最後にあり、それを見つけて送信するまでには長い時間がかかりました。

P. S.編集downvoteを削除する:)

+0

バージョン5.1.35を使用しています。インデックスが使えないのはなぜですか? –

+0

'@Jack M.':私の投稿は理由を説明しています。 – Quassnoi

+0

'@Jack M.':あなたはあなたのdownvoteを説明できますか? – Quassnoi

-8

私はあなたがデータ低速のネットワーク接続の多くを転送すると思います。

select *の代わりに、本当に必要な列だけを選択します。

テーブルに大きいテキストフィールドが含まれている場合、結果に表示する部分文字列を使用して、テキストの最初の数文字/単語のみを転送できます。

一部のクライアントでは、結果パケットの圧縮がサポートされています。たぶん、あなたはそれを見てみたいです。

+2

これはlocalhostから実行され、100件の結果しか返さず、ほとんどの結果は1つの電子メールアドレスと1つの名前です。大量のデータではなく、遅い接続。 –

関連する問題