1億5000万行のMySQLテーブルがあります。以下はそのデータ構造です。
以下はそのデータの一部です。
ここで、PHP MyAdminを使用して次のコマンドを実行しました。
SELECT `iwords` FROM `wordstable` WHERE `iwebs` = "a1"
クエリの実行に1秒もかからなかったと書かれています。以下がその証拠です。
でも実はデータを表示するのに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秒かかる場合、それは役に立ちません。
以下は私の高レベルのテーブルの詳細の一部です。
以下はサーバーマシンの詳細です
だから私の質問は、MySQLが本当にこの仕事をすることができるかということです。 MySQLによると、クエリの操作にかかる時間はそれほど長くありませんでしたが、実際にはなぜこれほど多くの時間がかかるのでしょうか。私の将来のデータベースはこれよりも大きくなり、数十億のレコードになります。この操作は少なくとも2〜3秒以内に完了する必要があります。
更新
SOメンバーの要求に応じて、以下のコマンドを実行し、その結果を投稿しています。
InputEXPLAIN SELECT iwords FROM wordstable WHERE iwebs = 'a1';
結果
入力
SET profiling=1;
SELECT iwords FROM wordstable WHERE iwebs = 'a1';
SHOW profile;
出力
最後に、リモートデスクトップを使用してこのサーバーにアクセスしていますが、すべてのコードとすべてがサーバー内で実行されました。
そのテーブルにインデックスはありますか?
次の出力を投稿してください:
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;
クエリがキャッシュされていると思います。試してみてください
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が起動すると、ディスクテーブルがメモリにロードされます。