MySQL查询挂起`SELECT COUNT(*)`

时间:2016-04-25 13:42:17

标签: mysql sql

我一直在玩MySQL和sqlalchemy来收集和存储数据。在周末,我以大约20,000条推文/小时收集推文,并将它们放在由他们的推文ID索引的表raw_tweets中。我期待约1,000,000行,但是当我运行时

SELECT COUNT(*) from raw_tweets;

查询只是挂起。我等了几分钟,但仍然没有。我对sql的了解相当有限。桌子上有锁可能吗?这会导致它挂起而不会引起错误吗?我该如何诊断/解决这个问题?

P.S。看起来我桌上的所有查询都悬而未决。

3 个答案:

答案 0 :(得分:2)

您可以在另一个数据库连接中运行以下命令(如果您有足够的权限这样做):

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列。

答案 1 :(得分:2)

很可能它不会挂起但需要很长时间才能执行。

如果表引擎是InnoDBSELECT 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返回的值会在每次后续运行中发生更改,即使表中没有写入活动也是如此。

答案 2 :(得分: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);

试试这个