2012-01-27 11 views
1

私は10M行の単純なMYSQLテーブルを持っています。最適化が必要ですが、なぜこの単純な選択に時間がかかりすぎるのか分かりません。それは結果をストリーミングする前に、クエリ時間のようです。WHERE句を使用しないSQLクエリの最適化

セットアップパフォーマンスチューニングに関する良いリンクはありますか?非常に日付例:http://www.mysqlperformanceblog.com/2006/09/29/what-to-tune-in-mysql-server-after-installation/

##QUERY: 
SELECT * FROM scga_results; 

mysql-slow.log 
# Time: 120126 15:05:03 
# [email protected]: abc[abc] @ localhost [] 
# Query_time: 25 Lock_time: 0 Rows_sent: 11896464 Rows_examined: 11896464 
select * from scga_results; 

##REF 
mysql> describe scga_results; 
+--------------+------------------+------+-----+-------------------+----------------+ 
| Field  | Type    | Null | Key | Default   | Extra   | 
+--------------+------------------+------+-----+-------------------+----------------+ 
| id   | int(10) unsigned | NO | PRI | NULL    | auto_increment | 
| application | varchar(255)  | NO | MUL |     |    | 
| field  | varchar(255)  | YES |  | NULL    |    | 
| value  | varchar(255)  | YES |  | NULL    |    | 
| period  | varchar(255)  | YES | MUL | NULL    |    | 
| end_time  | varchar(255)  | YES |  | NULL    |    | 
| date_updated | timestamp  | NO |  | CURRENT_TIMESTAMP |    | 
+--------------+------------------+------+-----+-------------------+----------------+ 
7 rows in set (0.00 sec) 

mysql> show table status like 'scga_results'\G 
*************************** 1. row *************************** 
      Name: scga_results 
     Engine: MyISAM 
     Version: 10 
    Row_format: Dynamic 
      Rows: 11897025 
Avg_row_length: 96 
    Data_length: 1152314616 
Max_data_length: 281474976710655 
    Index_length: 180028416 
     Data_free: 0 
Auto_increment: 11971193 
    Create_time: 2012-01-26 13:32:57 
    Update_time: 2012-01-27 00:20:04 
    Check_time: 2012-01-26 13:39:19 
     Collation: latin1_swedish_ci 
     Checksum: NULL 
Create_options: 
     Comment: 
1 row in set (0.00 sec) 

クエリの詳細を追加

USES KEY: 
mysql> explain select * from scga_results where application="20000"; 
+----+-------------+--------------+------+---------------+---------+---------+-------+------+-------------+ 
| id | select_type | table  | type | possible_keys | key  | key_len | ref | rows | Extra  | 
+----+-------------+--------------+------+---------------+---------+---------+-------+------+-------------+ 
| 1 | SIMPLE  | scga_results | ref | index_2  | index_2 | 257  | const | 1 | Using where | 
+----+-------------+--------------+------+---------------+---------+---------+-------+------+-------------+ 
1 row in set (0.26 sec) 

NO KEY USED: 
mysql> explain select * from scga_results where id="20"; 
mysql> explain select * from scga_results where period="day"; 
mysql> explain select * from scga_results where application>0; 

あなたはデータの1ギガバイト、より多くを取得しているように見えます

mysql> SET PROFILING=1; 
mysql> SELECT * FROM scga_results; 

------------------+---------------------+ 
11897787 rows in set (23.05 sec) 

mysql> show profiles; 
+----------+-------------+-----------------------------+ 
| Query_ID | Duration | Query      | 
+----------+-------------+-----------------------------+ 
|  1 | 6.72981800 | select id from scga_results | 
|  2 | 23.06871000 | select * from scga_results | 
+----------+-------------+-----------------------------+ 
2 rows in set (0.00 sec) 

mysql> SHOW PROFILE FOR QUERY 2; 
+--------------------------------+-----------+ 
| Status       | Duration | 
+--------------------------------+-----------+ 
| (initialization)    | 0.000008 | 
| checking query cache for query | 0.000047 | 
| checking permissions   | 0.00001 | 
| Opening tables     | 0.000013 | 
| System lock     | 0.000007 | 
| Table lock      | 0.000026 | 
| init       | 0.000023 | 
| optimizing      | 0.000006 | 
| statistics      | 0.000015 | 
| preparing      | 0.000013 | 
| executing      | 0.000004 | 
| Sending data     | 23.055196 | 
| end       | 0.000018 | 
| query end      | 0.000007 | 
| freeing items     | 0.000014 | 
| closing tables     | 0.000009 | 
| logging slow query    | 0.013294 | 
+--------------------------------+-----------+ 
17 rows in set (0.01 sec) 
+1

'WHERE'節がなければ、データベースがデータセット全体(10M行)を通過するように強制していることに注意してください。ディスクが遅い場合は、25秒かかることがあります。 – Chris

+0

これは単純な選択ではなく、むしろ最悪の選択です。ディスクからすべてのページを読み取るフルテーブルスキャンを実行します。インデックス付きフィールドで条件を指定しないと、クエリ時間が悪くなります。テーブルstatは集められ、インデックスは再構築されなければなりません.... –

+0

'application'カラムは' WHERE application> 0'を実行するvarcharですか? –

答えて

3

プロファイルの詳細を追加。本当にすべてのデータをもっと速く必要とするなら、ハードウェアの変更が必要になると思います。

サーバー上の他の負荷のためにクエリが必要以上に遅くなっている可能性がありますが、ハードウェアが提供できるものの限界に達している可能性があります。

高速なハードドライブ、特定のタイプのRAIDハードドライブ、または何らかのソリッドステートメモリに切り替えることもできます。テーブルをRAMテーブルに変換してRAMに保持することもできます。

+0

これは、MySQLの設計上の欠陥またはチューニングの問題でなければなりません。単純な 'SELECT * FROM table'は、結果をストリーミングする前に、実行に30秒かかります。テーブルスキャンや解釈があってはいけませんか?変更する - min-examine-row-limit強制的にMySQLが結果を送信する/テーブルスキャンをスキップする – celeryandsprite

+0

@ニック:すべての行が必要な場合は、すべての行をテーブルから読み込む必要があります(通常はディスクにあります)。それはテーブルスキャンです。 –

+0

@ypercube私はMySQLがすべての結果を送信する前にそれを読むとは信じられませんか?私は[チューニングスクリプト](http://www.day32.com/MySQL/)を実行して、これをいくつか読んでいます:http://dev.mysql.com/doc/refman/5.0/en/memory- use.html。パフォーマンス:$ topを読んでいる間に%65、%メモリ0.3%でCPUを示しています。 CPU 7%、メモリ58%を送信している間。私のテーブルは大きくなります... – celeryandsprite