我一直在玩MySQL和sqlalchemy来收集和存储数据。在周末,我以大约20,000条推文/小时收集推文,并将它们放在由他们的推文ID索引的表raw_tweets
中。我期待约1,000,000行,但是当我运行时
SELECT COUNT(*) from raw_tweets;
查询只是挂起。我等了几分钟,但仍然没有。我对sql的了解相当有限。桌子上有锁可能吗?这会导致它挂起而不会引起错误吗?我该如何诊断/解决这个问题?
P.S。看起来我桌上的所有查询都悬而未决。
答案 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 |
您应该仔细查看Command
和Info
列。
答案 1 :(得分: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
返回的值会在每次后续运行中发生更改,即使表中没有写入活动也是如此。答案 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);
试试这个