1

遺伝子テーブルから、位置情報を指定して最も近い遺伝子を見つけようとしています。次に例を示します。

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

私のテストの実行はかなり遅く、問題があります。

これは、EXPLAINデフォルトのインデックス付け(by 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)するか、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 name chrom chrom bin name name name2 name2 cdsStart cdsEnd exonCount exonStarts exonEnds score name2 cdsStartStat cdsEndStat exonFrames chrom chrom bin name 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

あなたの場合(単一のテーブルに対するクエリ、結合なし、複雑なものなし)、各列の値の分布を理解し、データベースサーバーがインデックスをどのように利用するかを理解することが重要です。さまざまな値の範囲がかなり広いフィールドがある場合は、そのフィールドをインデックス作成に使用する必要があります。(たとえば、上のインデックスはデータ全体をまたはstrandに分割し、ダウンストリームフィルターはいずれかまたは結果セットの各行を処理する必要があります。これは最悪の場合に近いです)+-+-

txStartこれまでのところ、クエリの興味深い列の中で最も差別化された値の分布があることがわかっています。

したがって、クエリは間違いなくその列のインデックスクエリを利用する必要があります。ただし、ハッシュインデックスではなくbtreeインデックス(演算子<、などはbtreeでは高速ですが<=、ハッシュ>では高速ではありません)。

単一の(btree)インデックスをオンにして再試行しtxStartます(すでに試行していることはわかっていますが、再試行して、すべてのセカンダリインデックスなどを避けてください)。

複数列のインデックスは優れていますが、その複雑さにより、単純な単一列のインデックスほど高速ではありません。MySQLオプティマイザーは、最適なインデックスを選択するのにかなり愚かです;-)

もう1つの重要な要素、動的な行サイズである可能性があります(longblob列を使用するため)。しかし、私はその点でMySQLの現在の状態について最新ではありません。

于 2013-02-26T03:59:37.183 に答える
1

必要なインデックスは次のとおり wgEncodeGencodeCompV12(chrom, strand, txstart)です。

一般に、インデックスの最初の列として等式のフィールドが必要です。次に、不等式のあるフィールドを1つ追加します。

于 2013-02-26T03:16:06.990 に答える