象と戯れ

 | 

2009-05-07

textsearch_senna updated!

00:53 | textsearch_senna updated! - 象と戯れ を含むブックマーク はてなブックマーク - textsearch_senna updated! - 象と戯れ

ツッコミを入れたら即座に答えが返ってきた。仕事が速いの何のって。。。頭が下がります。というわけで再度試してみた。

以前と同じデータで試すと、ちゃんとIndexScan→NestLoopでJOINを含めても数msec!SeqScan→HashJoinでは100msec近くかかっていたので、いい感じです。

これでいけるかな、と思ったらそうは問屋が卸さない。今度は10万件のうち9万件がヒットするキーワードでクエリを懸けたところ、LIKEより遅い。。。プランをみると、Senna側のSeqScan。演算子%%は何をするかというと、

static bool
SennaContains(text *doc, text *query)
{
	const char *str = VARDATA_ANY(doc);
	int			len = VARSIZE_ANY_EXHDR(doc);
	sen_query  *q;
	sen_rc		rc;
	int			found;
	int			score;

	q = SennaQuery(VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query));

	rc = sen_query_scan(q, &str, &len, 1, SEN_QUERY_SCAN_NORMALIZE, &found, &score);
	if (rc != sen_success)
		elog(ERROR, "senna: sen_query_scan() : code=%d", rc);

	return found && score;
}

sen_query_scanというのがSennaのSeqScanのようで。ノーマライズとかしてるしインデックスファイル自体はばかでかいはずなので、SeqScanはLIKEより遅いって寸法らしい。このsen_query_scan、SennaAPI一覧ページにも載っていないので仕様はよくわからんのですが。。。一方IndexScanはというと


Datum
senna_gettuple(PG_FUNCTION_ARGS)
{
	IndexScanDesc	scan = (IndexScanDesc) PG_GETARG_POINTER(0);
	ScanDirection	dir = (ScanDirection) PG_GETARG_INT32(1);

	SennaScanDesc  *desc = (SennaScanDesc *) scan->opaque;
	ItemPointerData ctid;

	if (dir != ForwardScanDirection)
		elog(ERROR, "senna: only supports forward scans");

	if (scan->kill_prior_tuple)
	{
		sen_index  *index = SennaIndexOpen(scan->indexRelation, false);
		text	   *value = extract_value(&scan->xs_ctup,
								scan->heapRelation, scan->indexRelation);

		SennaLock(scan->indexRelation, ExclusiveLock);
		SennaDelete(index, &scan->xs_ctup.t_self, value);
		SennaUnlock(scan->indexRelation, ExclusiveLock);
	}
(後略)

やはり別の方法でアクセスしています。いっそのことSeqScanでもインデックス読めばいいんじゃないか、と思ったのですが、インデックスしてなかったらどうするのか、というかSeqScanではインデックスのrelidがないのでそれはできない相談のような気がする。

コスト推定って重要だし難しいですね。



ところで、自分はPostgreSQLのためだけにsennaを使いたいので、そんなときのtextsearch_sennaのインストール手順。システムにちゃんとインストール出来る人は関係がないので読まないでください。そして、この情報はすぐ古くなる可能性があります。

ポイントは、sennaをシステムにインストールしていれば$PATHだのldconfigだのpkgconfigだのでパスがとれるのですが、今回はそうではないので、libsennaへのパスを指定する必要があります。

1.textsearch_sennaをどこかに置く。

postgresql/contribの下がベストです。そうすればPGXSがなくてもビルドできます。

2.senna-1.1.4をダウンロードして、textsearch_sennaのディレクトリに展開する。

3.sennaのビルド

cd textsearch_senna/senna-1.1.4/
./configure --without-mecab --prefix=/tmp/senna-tmp
make && make install
cp -p /tmp/senna-tmp/lib/libsenna* ../
cd ../

4.textsearch_sennaのMakefileを修正。

 - SHLIB_LINK = -lsenna
 + SHLIB_LINK = -L. -lsenna

5.make && make install

6.libsenna*をPostgreSQLインストールディレクトリのlib/にコピー

7.普通にpsql {db_name} -f textsearch_senna.sqlを実行

以上、何かの参考になれば。

PaitPait2011/08/21 05:55What a joy to find someone else who tnihks this way.

hwjmshhwjmsh2011/08/22 23:43c1ekES <a href="http://wblgosqvotyv.com/">wblgosqvotyv</a>

rppnmufbrppnmufb2011/08/24 03:14sSiiDH , [url=http://muelbvoyneyd.com/]muelbvoyneyd[/url], [link=http://kjsfadnacnlk.com/]kjsfadnacnlk[/link], http://hjqnsgkzloeu.com/

grmypusmxgrmypusmx2011/08/26 02:03QNy68B <a href="http://qoymbnlylici.com/">qoymbnlylici</a>

qbqazvgcnqbqazvgcn2011/08/31 20:09oBUeom , [url=http://ucxnlvfjuaid.com/]ucxnlvfjuaid[/url], [link=http://drqsufmikgew.com/]drqsufmikgew[/link], http://lsddfqfyxinp.com/

 |