0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SQLで全文検索を実装してはいけない理由【アンチパターン:プアマンズ・サーチエンジン】

Posted at

はじめに

全文検索をSQLのLIKE演算子で代用していませんか?
小規模なシステムでは一見動作しているように見えるこの設計は、実は「プアマンズ・サーチエンジン(Poor Man's Search Engine)」という有名なアンチパターンの一つです。

この記事では、この設計の問題点と、実際に取り入れるべき対策について具体的に解説します。

プアマンズ・サーチエンジンとは?

データベースのLIKEREGEXPを使って、あたかも全文検索のような動作を実現しようとする設計のことを指します。
特に以下のようなクエリが典型的です。

SELECT * FROM articles
WHERE title LIKE '%AI%' OR content LIKE '%AI%';

この方法は簡単に導入できる一方で、以下のような大きな問題を抱えています。

問題点

1. インデックスが使えない

LIKE '%キーワード%'のような前方一致ではない検索は、インデックスを活用できず、フルテーブルスキャンになります。
レコード数が増えるほど、検索速度が著しく低下します。

2. 検索の精度が低い

語幹(stem)や複数形、類義語などに対応できません。
たとえば「AI」で検索しても、「人工知能」や「機械学習」に関する記事がヒットしない可能性があります。

3. 表現の限界

関連度順のソート、マルチワード検索、ハイライト表示など、高度な検索機能をSQL単体では再現できません。

解決策

全文検索が必要であれば、SQLの機能に頼らず、適切な手段を選びましょう。

方法1:MySQLのFULLTEXT検索

ALTER TABLE articles ADD FULLTEXT(title, content);

SELECT * FROM articles
WHERE MATCH(title, content) AGAINST ('AI');

基本的な全文検索が可能になります。ただし日本語や特殊な言語では精度に課題があることも。

方法2:PostgreSQLの全文検索機能(tsvector)

ALTER TABLE articles ADD COLUMN document tsvector;

UPDATE articles
SET document = to_tsvector('english', title || ' ' || content);

CREATE INDEX idx_document ON articles USING GIN(document);

SELECT * FROM articles
WHERE document @@ to_tsquery('AI');

多言語対応や構文の柔軟性、検索の精度でMySQLよりも優れた選択肢です。

方法3:専用の全文検索エンジンを導入する

  • Elasticsearch
  • Apache Solr
  • Meilisearch

これらは本格的な全文検索機能を提供し、検索速度・精度・拡張性の点で非常に優れています。

まとめ

方法 メリット デメリット
LIKE演算子 実装が簡単 遅い、精度低い
FULLTEXT(MySQL) 高速で基本機能に対応 日本語処理に限界
tsvector(PostgreSQL) 精度・速度ともに良好 実装がやや複雑
検索エンジン 多機能で拡張性抜群 学習・導入コストあり

一時しのぎの検索ではなく、長期的に使える検索体験を設計するために、今すぐ「プアマンズ・サーチエンジン」から卒業しましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?