2009-08-15 21 views
3

私は名前と別のフィールドで検索するMySQL(ストアドプロシージャで使用される)でクエリを持っています。これらの検索パラメータをさまざまに組み合わせて使用​​すると、1〜2秒という速い結果が得られますが、特定の値を指定すると、9秒かかる結果がウェブサイトに表示されます。 次は私がEXPLAIN文の外に出たものです:遅いMySQLクエリ

id, select_type, table, type, possible_keys, key,  key_len, ref, rows, Extra 
-------------------------------------------- 
1, SIMPLE,  Names, ref, IX_Name,  IX_Name, 17,  const, 3173, Using where 

名前はVARCHAR(40)として宣言され、他のフィールドは、符号なしSMALLINT(6)です。私はクエリで使用されている名前(IX_Name)の最初の15文字にインデックスを使用しています。遅いクエリでは、EXPLAIN出力の「行」列をチェックするために非常に多くの行が取得されることがわかります。

私はパフォーマンスを向上させるために何ができるかわかりません。上のEXPLAINの出力に何か間違っていますか?

おかげで、 ティム

+2

遅い実行クエリを投稿することをお勧めします。 – karim79

+1

SQL文を表示できますか?また、テーブルに格納されている名前の基数を知ることも有益です。 – DBMarcos99

答えて

3

はどのようにテーブルを投入しましたか?インデックスはツリー構造であり、効率的に動作するためには、テーブルがバッチでロードされるか定期メンテナンスが適用されると自動的に行われます。これらのどちらも真でない場合、過度に成長したツリーの部分では、インデックスの効率が大幅に低下します。

最も単純なチェックは、インデックスを削除してもう一度再作成することです。後で同じ行動を取った場合、それは別のものですが、少なくともそれが排除される可能性があります。

+0

こんにちはCruachan。 ご返信ありがとうございます。私はMYISAM 400万行のテーブルを持っており、毎週更新しています。私は毎週約2000行の更新を行うと、次の文を実行します。 namenumber descで順序を変更します。 テーブル名を最適化します。 テーブル名を分析する。 しかし、インデックスを変更したり、再作成したりすることはありません...インデックスが不均衡かもしれないと言ったように、それは問題になる可能性がありますか?それはなぜそれが特定の名前でしか起こらないのかを説明するためです。 ありがとう、 チーム –

+0

インデックスを削除して試してみるとよいでしょう。私は大規模なMySQLデータベースをDBAすることはなかったので、私は直接の経験はありませんでしたが、確かにこれは私が管理していたいくつかの非常に大きなOracleデータベースに当てはまりました。一般的に、人々はテーブル構造に集中し、インデックスもストレージ構造であり、管理する必要があることを忘れてしまいます。 – Cruachan

+0

結果を投稿していただければ幸いです。 – Cruachan

1

いいえ、プレフィックスにはインデックスがあります。バーブ ビル ビフ ボブはバック はカール

バド ボニー ベッツィ ベス アル

:あなたは、最初の15個の文字を使用しますが、あなたは1つだけを使用し、あなたのテーブルには名前のためにこれらの値を持っていたふりをしましょう

私のインデックスは最初の文字にしかないので、データベースはインデックスが返すすべての行を読み込み、各名前全体を述語と比較する必要があります。

ここで、「Al」を探すと、インデックスが1行戻ってきます。私はそれから、列の中の「Al」と言い張りの中の「Al」を比較します。そして私は一致があるので、その行を返します。

私が 'Alex'を探すと、インデックスが1行戻ってきます。私はそれから、列の中の「Al」とのプレテートの「Alex」を比較し、一致がなくなり、それ以上の可能性のある試合はなくなりました。

私が '芽'(または 'B'で始まるもの)を探すと、私のインデックスは9行戻します。私は、私が読む前に述語と比較する必要がある行が9行あります。

はこれを行います。

select substring(name, 1, 15), count(*) 
from names 
group by substring(name, 1, 15); 

私はあなたが多くの名前が共通の接頭辞を共有する場所が遅いものがある一方で、あなたの迅速な検索が持っている、ユニークで見つけることだと思います。

+0

返事ありがとうございました...事は、私は完全な名前(フ​​ィッシャー)を探しています。この場合、接頭辞は問題ではないと思います。とにかく15文字未満です。名前は15文字後にほぼ一意です。 ありがとう、 Tim –

0

ユーザーにレンダリングしたいと仮定して、かなり大きな数を考慮する3173行が見つかりました。実際に検索されるレコードの数が大幅に少ない場合は、より多くのインデックスを作成することを検討する必要があります。 EXPLAINが別の検索語に対して何を報告しているかを知ることは有用です。

2

クエリは1つのフィールドのインデックスのみを使用しているようです。あなたは名前と "別のフィールド"で検索することに言及しました。 MySQL(特定の状況では非常に最近のバージョンを除く)は、クエリ内のテーブルオカレンスあたり1つのインデックスに制限されています。つまり、nameのインデックスと他のフィールドのインデックスがある場合、MySQLはどのインデックスが最も有用かを推測し、他のインデックスは無視する必要があります。より良いクエリ構造やインデックス定義が役立つようです。あなたの名前がかなりユニークで、あなたが3,000行をExplainプランで取得している場合は、DBのメタデータが適切でないか、他のフィールドに他にもたくさんの可能性があります。

テーブルのクエリとスキーマを投稿できますか?

クエリは同じSQLに対して常に高速または常に遅いですか?フィッシャーを検索すると、時には速く、時には遅くなる、または一貫していることがあります。一貫性がある場合は、おそらくCPUまたはディスクのアクティビティによるものです。変数の場合は、おそらくDB上の他のクエリによるものです。

また、選択した内容に応じて、完全な結果をインデックスに追加することができれば、レコードを検証するためにディスクにヒットする必要がないため、クエリが実行されます。私は "インデックスを使用して"クエリでかなり驚くべき改善をしました。

Jacob