1

我试图从基因表中找到最接近的基因,给定位置信息。这是一个例子:

SELECT chrom, txStart, txEnd, name2, strand FROM wgEncodeGencodeCompV12 WHERE chrom = 'chr1' AND txStart < 713885 AND strand = '+' ORDER BY txStart DESC LIMIT 1;

我的测试运行非常缓慢,这是有问题的。

这是EXPLAIN带有默认索引的输出(按chrom):

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
| 1 | SIMPLE | wgEncodeGencodeCompV12 | ref | chrom | chrom | 257 | const | 15843 | Using where; Using filesort |

使用了 Filesort 并且可能导致所有缓慢?

(chrom, txStart, strand)我尝试通过 indexing或单独来加快排序txStart,但它只会变慢(?)。我的理由是,txStart它的选择性不足以成为一个好的索引,而在这种情况下,全表扫描实际上更快?

这是EXPLAIN带有附加索引的输出:

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
| 1 | SIMPLE | wgEncodeGencodeCompV12 | range | chrom,closest_gene_lookup | closest_gene_lookup | 261 | NULL | 57 | Using where |

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
| 1 | SIMPLE | wgEncodeGencodeCompV12 | range | chrom,txStart | txStart | 4 | NULL | 1571 | Using where |

表结构

CREATE TABLEwgEncodeGencodeCompV12 bin名称chrom strand txStart txEnd cdsStart cdsEnd exonCount exonStarts exonEnds score name2 cdsStartStat cdsEndStat exonFrames chrom chrom bin名称name name2 name2(
smallint(5) unsigned NOT NULL,
varchar(255) NOT NULL,
varchar(255) NOT NULL,
char(1) NOT NULL,
int(10) unsigned NOT NULL,
int(10) unsigned NOT NULL,
int(10) unsigned NOT NULL,
int(10) unsigned NOT NULL,
int(10) unsigned NOT NULL,
longblob NOT NULL,
longblob NOT NULL,
int(11) default NULL,
varchar(255) NOT NULL,
enum('none','unk','incmpl','cmpl') NOT NULL,
enum('none','unk','incmpl','cmpl') NOT NULL,
longblob NOT NULL,
KEY
(,),
KEY
(),
KEY
()
)

有没有办法让这更有效?我很感激你的时间!

(更新)解决方案: 结合两个评论者的建议显着提高了运行时间。

4

2 回答 2

1

您想要的索引是: wgEncodeGencodeCompV12(chrom, strand, txstart)

通常,您希望将具有等式的字段作为索引中的第一列。然后添加一个不等式的字段。

于 2013-02-26T03:16:06.990 回答
1

在您的情况下(对单个表进行查询,没有连接,没有复杂的东西),了解每列中值的分布以及了解数据库服务器如何利用索引非常重要。当您有一个具有相当大范围不同值的字段时,应该使用该字段进行索引。(例如,一个索引strand只会将整个数据拆分为+or-并且下游过滤器必须处理+or 或-结果集的每一行,这接近最坏的情况)

到目前为止,我们知道txStart在您的查询的有趣列中具有最差异化的值分布。

因此,您的查询绝对应该在该列上使用索引查询!但是 btree 索引,而不是哈希索引(运算符<,<=>在 btree 上很快,但在哈希上不快)。

仅使用单个(btree)索引再试一次txStart(我知道您已经尝试过,但请再试一次并避免所有二级索引等)。

多列索引很好,但它们的复杂性使它们不如普通的单列索引快,MySQLs 优化器在选择最佳索引时相当愚蠢;-)

另一个重要因素可能是动态行大小(因为使用longblob列)。但在这方面,我对 MySQL 的当前状态不是最新的。

于 2013-02-26T03:59:37.183 回答