1

データベースから削除されたドメイン名を選択する動的クエリを作成しています。現時点では 12 行ありますが、すぐに最大 500,000 行のレコードを持つデータを取得する予定です。

スキーマは、4 つの列を含む 1 つのテーブルです。

CREATE TABLE `DroppedDomains` (
  `domainID` int(11) NOT NULL AUTO_INCREMENT,
  `DomainName` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `DropDate` date DEFAULT NULL,
  `TLD` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`domainID`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

私はスキーマを作成しませんでした。これはライブ データベース スキーマです。サンプルデータは次のとおりです。

ここに画像の説明を入力

おそらく最も複雑なタイプのクエリを以下に作成しました。基準は次のとおりです。

任意の数のドメインを選択します。

  1. 「はじまる」から始める
  2. 「終わる」で終わる
  3. ドメイン名の任意の場所に「containsThis」という単語が含まれている
  4. ドメイン名の任意の場所に「ContainsThisToo」という単語が含まれている
  5. 少なくとも 1 つの数字を含める
  6. ドメイン名は 49 文字以上にする必要があります。マルチバイトは 1 文字としてカウントする必要があります (私は CHAR_LENGTH を使用しました)。
  7. ドメイン名は 65 文字以上にする必要があります。
  8. TLD は「org」でなければなりません
  9. DropDate は、2009-11-01

これまでの私のクエリは次のとおりです。

SELECT
*
FROM
DroppedDomains

WHERE

1=1

AND DomainName LIKE 'starts%ends'
AND DomainName LIKE '%containsThis%'
AND DomainName LIKE '%containsThisToo%'
AND DomainName LIKE '%-%'
AND DomainName REGEXP '[0-9]'
AND CHAR_LENGTH(DomainName) > 49
AND CHAR_LENGTH(DomainName) < 65
AND TLD = 'org'
AND DropDate > '2009-11-01'

ここに私の質問があります

  1. TLD列を独自のテーブルにして、TLD列をその外部キーにするだけで、50 万行になることを考えると、パフォーマンスが大幅に向上しますか? TLD は 5 つだけです (com、net、org、info、biz)。現実世界にはもっと多くの TLD があることはわかっていますが、このアプリケーションには 5 つしかありません。ユーザーは独自の TLD を指定できません。

  2. 私はそれを知っていREGEXPます.500,000行はおそらく災害のレシピです. とにかく回避できることはありREGEXPますか?

  3. 私ができるクエリに対する他の最適化はありますか? mergeLIKEのように、または多分などの他の関数を使用しINSTRますか?また、特定の種類のキャッシュ メカニズムを実装する必要がありますか?

4

2 に答える 2

3

定数プレフィックスで始まる LIKE パターンがあり、そのフィールドにインデックスがある場合、インデックスを使用して、プレフィックスで始まる行を非常に迅速に見つけることができます。幸いなことに、まさにこの状況がここにあります。

AND DomainName LIKE 'starts%ends'

数個の値のみで始まる場合starts、これらの行は非常に迅速に検出され、他の式はこれらの行に対してのみテストされます。を実行すると、インデックスが使用されていることを確認できますEXPLAIN SELECT ...

于 2011-03-12T21:42:01.483 に答える
1

使用するクエリに従って作成するインデックスを計画する必要があります。

  • DropDate のみでフィルタリングするクエリがある場合は、DropDate のインデックスが役立ちます。
  • TLD でグループ化するクエリがある場合は、TLD のインデックスが役立ちます。
  • DomainName の長さだけで検索するクエリがある場合は、クエリを実行するたびに長さが計算されないように、DomainNameLength フィールドを追加することを検討してください。
  • 2 つのフィールド (TLD と DropDate など) で検索 (フィルター処理) するクエリがある場合は、おそらくこれらのフィールドに 2 列のインデックスが必要です。
  • 等...

使用する唯一のクエリが複雑なものである場合は、Mark のアドバイス (DomainName のインデックスについて) が最適です。

フィールドに関する質問 1 についてTLD:

このためのオプションが本当に少数 (5 など) しかなく、利用可能なすべての tld を使用する予定がない場合は、ENUMtypeを使用できます。

CREATE TABLE(
   ....
   tld ENUM('com', 'net', 'org', 'info', 'biz')
)
于 2011-03-13T02:40:40.913 に答える