2016-04-25 17 views
1

私はMySQLとsqlalchemyを使ってデータを収集して保存しています。週末には約20,000回のつぶやきでツイートを収集し、そのツイートIDによってインデックス化されたテーブルraw_tweetsに配置しました。 〜1,000,000行を期待していますが、実行するとMySQLのクエリが `SELECT COUNT(*)`でハングアップ

SELECT COUNT(*) from raw_tweets; 

クエリがハングアップします。私は数分待って、まだ何もしていない。私の知識はかなり限られています。テーブルにロックがある可能性はありますか?それはエラーを引き起こさずにハングアップするのだろうか?どのように私はこの問題を診断/修正することができますか?

P.S.そのテーブルのすべてのクエリがハングアップしているように見えます。

+4

明らかにテーブルにロックがあります。 – HLGEM

+1

あなたはraw_tweetsからSELECT COUNT(id)のようなクエリを正規化することができます。 –

+1

'id'フィールドが主キーであるとしましょう。 @SagarRが悲しいので、 'SELECT COUNT(id)FROM raw_tewgets'を使うべきです。 – vaso123

答えて

2

は、おそらくそれがハングアップするが、実行には非常に多くの時間を必要としませんしてみてください。

テーブルエンジンがInnoDBの場合、SELECT COUNT(*)はテーブルからすべての行を(その数をカウントするために)読み取らなければならず、データベースが大量に使用されている場合、操作に多くの時間がかかります。

これはLimits on InnoDB Tablesページに記載されて:同時実行トランザクションが同時に行の異なる数を「見る」可能性があるため、

InnoDBはテーブル内の行の内部カウントを保持しません。 SELECT COUNT(*) FROM t文を処理するために、InnoDBはテーブルのインデックスをスキャンします。インデックスが完全にバッファプールにない場合、時間がかかります。高速カウントを取得するには、自分で作成したカウンターテーブルを使用して、挿入や削除に応じてカウンターテーブルを更新する必要があります。おおよその行数で十分なら、SHOW TABLE STATUSを使用できます。

あなたが実行のためのおおよその行数が十分であるかのように、上記で説明:

SHOW TABLE STATUS WHERE NAME = 'raw_tweets' 
をし、その結果の Rows列に見えます。

ご注意:

  • SHOW TABLE STATUSによって返される行の数はおおよそのものです。数パーセントで実際の値から外れる可能性があります(テーブルが小さい場合はその差が大きくなります)。
  • SHOW TABLE STATUSによって返される値は、テーブルに書き込みアクティビティがない場合でも、後続の各実行時に変更されます。
+0

これはまさに私が必要としていたものです。データが収集されたかどうかを確認していたので、おおよその数字で十分です。私はInnoDBの限界を認識していませんでした。 – Shatnerz

+0

あなたのテーブルが古い 'MyISAM'エンジンを使用していた場合、エンジンは値を保持し更新するので、' SELECT COUNT(*) 'は直ちに完了します。おそらくそれを変換するのは遅すぎるでしょう。 – axiac

1

あなたは別のデータベース接続(あなたがそうするための十分な権限を持っている場合)に次のように実行できます。

現在使用しているデータベース上で実行されているすべてのクエリ/プロセスが表示される場合があります
SHOW FULL PROCESSLIST; 

。そのリストでは、テーブル

mysql> show full processlist; 
+---------+------------+-----------------+------------+---------+------+-------+-----------------------+ 
| Id  | User  | Host   | db   | Command | Time | State | Info     | 
+---------+------------+-----------------+------------+---------+------+-------+-----------------------+ 
| 121904 | user01  | localhost  | user_db | Locked | 0 |  | SELECT * FROM usr_tbl | 
| 1186598 | root  | localhost  | NULL  | Query | 0 | NULL | show full processlist | 

に設定されたいくつかのロックがある場合は、CommandInfo列を詳しく見てみなければならない表示される場合があります。

0
SELECT row_count = SUM(row_count) 
    FROM sys.dm_db_partition_stats 
    WHERE [object_id] = OBJECT_ID('raw_tweets') 
    AND index_id IN (0,1); 

この

+0

これは本当に良い応答ですが、なぜそれがより速いのか説明できますか?おかげで –

+0

@AxelGuilmin:あなたの感謝のおかげで、まずインデックス付きテーブルを使用していると書いていますので、私の解決方法は部分的にあなたの問題に合っています。私たちはindex_idを使っているので、あなたのIDにプライマリキーを持っているので、Count(*)を使う代わりにCount(PRIMARYKEY FIELD)を使うのがベストプラクティスです。 –