5

该表在 InnoDB 表中。以下是一些可能有用的信息。

EXPLAIN SELECT COUNT(*) AS y0_ FROM db.table this_ WHERE this_.id IS NOT NULL;

+----+-------------+-------+-------+---------------+---------+---------+------+---------+--------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows    | Extra                    |
+----+-------------+-------+-------+---------------+---------+---------+------+---------+--------------------------+
|  1 | SIMPLE      | this_ | index | PRIMARY       | PRIMARY | 8       | NULL | 4711235 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+---------+--------------------------+
1 row in set (0.00 sec)

mysql> DESCRIBE db.table;
+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id           | bigint(20)   | NO   | PRI | NULL    |       |
| id2          | varchar(28)  | YES  |     | NULL    |       |
| photo        | longblob     | YES  |     | NULL    |       |
| source       | varchar(10)  | YES  |     | NULL    |       |
| file_name    | varchar(120) | YES  |     | NULL    |       |
| file_type    | char(1)      | YES  |     | NULL    |       |
| created_date | datetime     | YES  |     | NULL    |       |
| updated_date | datetime     | YES  |     | NULL    |       |
| createdby    | varchar(50)  | YES  |     | NULL    |       |
| updatedby    | varchar(50)  | YES  |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+
10 rows in set (0.05 sec)

解释查询给了我结果。但是实际的查询已经运行了很长一段时间。我怎样才能解决这个问题?我究竟做错了什么?

我基本上需要弄清楚photos这张表中有多少。最初,原始编码器有一个检查过的查询WHERE photo IS NOT NULL(花费了 3 小时以上),但我更改了此查询以检查该id列,因为它是主键。我预计那里会有巨大的性能提升,并期待在一秒钟内得到答案,但似乎并非如此。

我需要对数据库进行哪些优化?我认为查询很好,但如果我错了,请随时纠正我。

编辑:mysql Ver 14.14 Distrib 5.1.52,用于 redhat-linux-gnu (x86_64) 使用 readline 5.1

PS:出于某种疯狂的原因,我重命名了表格。我实际上没有名为 db 的数据库和名为 table 的表。

4

1 回答 1

12

“长”有多长?这个表有多少行?

MyISAM 表会跟踪它有多少行,所以一个简单的 COUNT(*) 几乎总是会立即返回。

另一方面,InnoDB 的工作方式不同:InnoDB 表不跟踪它有多少行,所以当你 COUNT(*) 时,它实际上必须去计算每一行。如果您有一张大桌子,这可能需要几秒钟。

编辑:尝试COUNT(ID)代替COUNT(*),其中ID没有 NULL 的索引列在哪里。那可能跑得更快。

EDIT2:如果您将文件的二进制数据存储在 longblob 中,您的表将非常庞大,这会减慢速度。

可能的解决方案:

  1. 使用 MyISAM 而不是 InnoDB。
  2. 保持您自己的计数,可能在插入和删除时使用触发器。
  3. 将二进制数据剥离到另一个表中,或者最好是常规文件。
于 2013-03-14T06:08:03.500 回答