web-dev-qa-db-ja.com

MySQLデータベースは非常に大きなテーブルで非常に遅くなります

1億5000万行のMySQLテーブルがあります。以下はそのデータ構造です。

enter image description here

以下はそのデータの一部です。

enter image description here

ここで、PHP MyAdminを使用して次のコマンドを実行しました。

SELECT `iwords` FROM `wordstable` WHERE `iwebs` = "a1" 

クエリの実行に1秒もかからなかったと書かれています。以下がその証拠です。

enter image description here

でも実はデータを表示するのに1分くらいかかりました!!

そこで、Javaコードを実行して、時間を確認しました。以下のとおりです。

public void select(String str) 
{
    try {
        long startTime = System.currentTimeMillis();
        Statement s = con.createStatement();
        ResultSet executeQuery = s.executeQuery("SELECT `iwords` FROM `wordstable` WHERE `iwebs` = \"a1\" ");
        int r=0;
        long endTime = System.currentTimeMillis();
        System.out.println("Time took by Database: "+(endTime-startTime));

        while(executeQuery.next())
        {
            r++;
        }


        System.out.println("Number of rows: "+String.valueOf(r));

    } catch (SQLException ex) {
       ex.printStackTrace();
    }

}

このコードは、88.779秒である88779ミリ秒として時間を出力しました!

これは非常に大きな問題です。検索する単語の配列があります。「単一の」単語を検索するのに88秒かかる場合、それは役に立ちません。

以下は私の高レベルのテーブルの詳細の一部です。

enter image description here

以下はサーバーマシンの詳細です

enter image description here

だから私の質問は、MySQLが本当にこの仕事をすることができるかということです。 MySQLによると、クエリの操作にかかる時間はそれほど長くありませんでしたが、実際にはなぜこれほど多くの時間がかかるのでしょうか。私の将来のデータベースはこれよりも大きくなり、数十億のレコードになります。この操作は少なくとも2〜3秒以内に完了する必要があります。

更新

SOメンバーの要求に応じて、以下のコマンドを実行し、その結果を投稿しています。

InputEXPLAIN SELECT iwords FROM wordstable WHERE iwebs = 'a1';

結果 enter image description here

入力

SET profiling=1;
SELECT iwords FROM wordstable WHERE iwebs = 'a1';
SHOW profile;

出力

enter image description here

最後に、リモートデスクトップを使用してこのサーバーにアクセスしていますが、すべてのコードとすべてがサーバー内で実行されました。

1
Lemon Juice

そのテーブルにインデックスはありますか?

次の出力を投稿してください:

EXPLAIN SELECT iwords FROM wordstable WHERE iwebs = 'a1';

次に、次の一連のコマンドの出力を投稿します。

SET profiling=1;
SELECT iwords FROM wordstable WHERE iwebs = 'a1';
SHOW profile;

これにより、MySQLがハングする場所がわかり、少なくともどこから始めればよいかがわかります。

更新:

更新された質問を見た後、MySQLがクエリを実行するのに適したキーを見つけられない理由がわかりません。 'iwebs'に含めることができる値のセットはどれくらい広大ですか?期間は明らかにキャッシュから取得されます。 MySQLクエリキャッシュをリセットする必要があります

RESET QUERY CACHE;

リロード権限がある場合は、それ以外の場合は使用する必要があります

FLUSH QUERY CACHE;

このコマンドも実行できない場合は、MySQLサーバーインスタンスを再起動する必要があります。

Nebuが言ったように、SQL_NO_CACHEフラグを使用してコマンドを再実行し、邪魔にならないようにします。

そう:

EXPLAIN SELECT SQL_NO_CACHE iwords FROM wordstable WHERE iwebs = 'a1';
SET profiling=1;
SELECT SQL_NO_CACHE iwords FROM wordstable WHERE iwebs = 'a1';
SHOW profile;
4
Andrea

クエリがキャッシュされていると思います。試してみてください

SELECT SQL_NO_CACHE iwords FROM wordstable WHERE iwebs = 'a1';

これにより、クエリの実行にかかる時間がわかりやすくなります。また、iwebがインデックスに登録されていることを確認してください。そして最後に、クエリを本当に高速化するために、テーブルをメモリに保存します。

CREATE TABLE ii_table(....)ENGINE = MEMORY DEFAULT CHARSET = utf8

テーブルをメモリに保存することには、いくつかの影響があります。たとえば、mysqlサーバーが停止するたびに、テーブル情報は失われます。個人的にこのような状況のために、私は2つのテーブルを作成します。クエリが実行される1つのメモリテーブルと1つのディスクテーブル。 mysqlが起動すると、ディスクテーブルがメモリにロードされます。

1
Nebu