web-dev-qa-db-ja.com

SQLテーブルの何百万ものレコードをより速く検索するにはどうすればよいですか?

何百万ものドメイン名を持つSQLテーブルがあります。しかし今私が検索するとき言いましょう

SELECT * 
  FROM tblDomainResults 
 WHERE domainName LIKE '%lifeis%'

結果が出るまで10分以上かかります。インデックスを作成しようとしましたが、役に立ちませんでした。

この数百万のレコードを保存し、これらの情報に短期間で簡単にアクセスするための最良の方法は何ですか?

これまでに約5000万件のレコードと5列があります。

13
user737063

ほとんどの場合、パターンが固定文字列で始まらない限り、LIKEクエリの最適化に使用できない従来のインデックスを試しました(例: 'lifeis%')。

クエリに必要なのはフルテキストインデックスです。最近のほとんどのDBMSはそれをサポートしています。

12
Igor Nazarenko

ここでは、フルテキストインデックス作成が最も優れたオプションです。これを実現する方法は、使用しているDBMSによって異なります。

それを除いて、パターンと一致する列のインデックスがあることを確認してくださいwillパフォーマンスを向上させますが、その音によって、これを試しましたが、あまり役に立ちませんでした。

6
Will A

5,000万行のテーブルに重複が含まれていると仮定し(おそらくそれは問題の一部です)、SQL Server(構文は変更される可能性がありますが、概念はほとんどのRDBMSで類似しています)を想定すると、別のオプションはドメインをルックアップテーブルに格納することです。

CREATE TABLE dbo.Domains
(
    DomainID INT IDENTITY(1,1) PRIMARY KEY,
    DomainName VARCHAR(255) NOT NULL
);
CREATE UNIQUE INDEX dn ON dbo.Domains(DomainName);

新しいデータをロードするときは、ドメイン名のいずれかが新しいかどうかを確認し、それらをDomainsテーブルに挿入します。次に、大きなテーブルにDomainIDを含めるだけです。これにより、5,000万行のテーブルがはるかに小さくなるだけでなく、このようなルックアップがはるかに効率的になります。

SELECT * -- please specify column names
FROM dbo.tblDomainResults AS dr
INNER JOIN dbo.Domains AS d
ON dr.DomainID = d.DomainID
WHERE d.DomainName LIKE '%lifeis%';

もちろん、最も小さなテーブルを除いて、先頭にワイルドカードが付いたLIKE句を回避することは常に役立ちます。

6
Aaron Bertrand

LIKEステートメントの使用を停止します。 全文検索 を使用できますが、MyISAMテーブルが必要であり、それだけでは十分ではありません。

LuceneSphinx などの利用可能なサードパーティソリューションを調べることをお勧めします。
彼らは優れているでしょう。

5
tereško

検討したいことの1つは、そのようなルックアップ用に別の検索エンジンを用意することです。たとえば、SOLR(lucene)サーバーを使用して、検索に一致するエントリのIDを検索および取得してから、IDによってデータベースからデータを取得できます。 2つの異なる呼び出しを行う必要がある場合でも、結果的に高速になる可能性が非常に高くなります。

3
RHSeeger

全文検索を使用して、数百万のレコードを検索できます... http://msdn.Microsoft.com/en-us/library/ms142571.aspx

3
Singh
1
dLcreations

インデックス自体に含まれていないデータをルックアップ(「ブックマークルックアップ」)する必要がある場合は常に、インデックスの速度が低下します。たとえば、インデックスにIDとNAMEの2つの列があるが、*(合計5列)を選択している場合、データベースは最初の2列のインデックスを読み取ってから、他の3列を検索する必要があります。どこか別の場所で効率の悪いデータ構造。

この場合、「いいね」のためにインデックスを使用できません。これは、クエリにwhereフィルタを配置しないのと似ています。とにかくテーブル全体を読み取る必要があるため、インデックスを完全にスキップします(「テーブルスキャン」)。しきい値があります(エンジンが通常これに反転する場合、約35〜50%だと思います)。

つまり、本番アプリケーションでDBから5,000万行すべてが必要になる可能性は低いと思われますが、必要な場合は、メモリの多いマシンを使用して、そのデータをメモリに保持する方法を試してください。たぶん、No-SQL DBの方が良いオプションでしょう-mongoDB、couch DB、tokyoキャビネット。このようなもの。幸運を!

0
Jody

ドメインをチャンクに分割してから、チャンク自体を検索することができます。数年前、文章の中の単語を検索する必要があったときに、そのようなことをしました。全文検索が利用できなかったので、文を単語リストに分割して単語を検索しました。単語にインデックスが付けられていたので、結果を見つけるのは本当に速かったです。

0
Scott Bruns