2010-07-22 66 views
6

我正在构建一个MySQL数据库,其中包含有关酵母物种中DNA的特殊子串的条目。我的表如下所示:对文本字段COUNT和GROUP BY似乎很慢

+--------------+---------+------+-----+---------+-------+ 
| Field  | Type | Null | Key | Default | Extra | 
+--------------+---------+------+-----+---------+-------+ 
| species  | text | YES | MUL | NULL |  | 
| region  | text | YES | MUL | NULL |  | 
| gene   | text | YES | MUL | NULL |  | 
| startPos  | int(11) | YES |  | NULL |  | 
| repeatLength | int(11) | YES |  | NULL |  | 
| coreLength | int(11) | YES |  | NULL |  | 
| sequence  | text | YES | MUL | NULL |  | 
+--------------+---------+------+-----+---------+-------+ 

大概有180万条记录。在一个类型的查询我想看看有多少DNA子与各类型品种和区域相关的,所以我发出这个查询:

select species, region, count(*) group by species, region; 

种类和地区列只有两个可能的条目(保守/ scer对于物种以及启动子/区域编码),但该查询大约需要30秒

这是一个正常的时间期望这种类型的查询给定的表的大小?这是慢的,因为我使用文本字段而不是简单的整数或布尔值(我喜欢文本字段,因为几个非CS研究人员将使用数据库)。任何其他想法和建议都会受到欢迎。

请原谅,如果这是一个头脑问题,我是一名SQL初学者。

P.S.我也看到了this question,但提议的解决方案似乎与我正在做的事情没有关系。

编辑:将这些字段转换为VARCHAR将运行时间减少到约2.5秒。注意我也对它有相似时间的ENUM进行计时。

+0

哪个字段是您的主键? – 2010-07-22 02:55:11

+0

我没有主键。我可以人为制造一个,但它会影响吗? – Rich 2010-07-22 04:17:32

回答

6

为什么所有基于字符串的列都定义为TEXT?如果阅读性能比较,您会发现TEXT比使用相同索引的VARCHAR列慢3倍:http://forums.mysql.com/read.php?24,105964,105964

+0

好的,没有注意到它们是'text'。 – 2010-07-22 03:15:50

+0

我做了TEXT,因为一个同事我说这和VARCHAR没有任何区别:)使用VARCHAR将我的运行时间从33秒缩短到了2.5秒 – Rich 2010-07-22 04:43:45

+0

@Rich:哇 - 没有想到会有这么大的差异,如果你将物种和区域列更改为保存其各自值的表的外键。INT总是4个字节,而VARCHAR(4)是5,因此您可以想象VARCHAR(100)有多少个字节。 – 2010-07-22 15:34:24

3

如果你的领域只有2个值,那么你最好使他们成为布尔值。除非有真正的原因,你应该把所有的东西都做成NOT NULLNULL

另请参阅ENUM type以更好地使用列的有限数量的可读取值。

至于速度慢,首先要尝试的是在您的列上创建索引。对于你在这里展示的特定查询,上species, region索引应该产生巨大的变化:

create index on mytablename (species, region); 

应该这样做。

+2

您确定该指数会与这种低基数数据产生巨大差异吗? – 2010-07-22 02:59:22

+1

不,我不确定,但我认为这是一个很好的猜测。我开始写一些关于使用'EXPLAIN'的文章,但它开始变成一堆蠕虫。我猜想最终结果可能是我们应该尝试创建索引。 – Vineet 2010-07-22 03:11:56

+0

我试过索引,但没有区别。我也尝试过VARCHAR,因为OMG Ponies建议它快得多。之后,我尝试了对枚举,而VARCHAR没有明显的加速。 – Rich 2010-07-22 04:42:49