4

長い変数 (100 ~ 250 文字などの URL) を持つ大きなテーブル (100000 以上のエントリ) があるとします。テーブルから単一の行をフェッチするために、MD5 ハッシュを別のフィールドとして横に持つことは、パフォーマンスを向上させるのに意味がありますか?

SELECT * FROM `urls` WHERE `url` = 'http://long-phrase...' LIMIT 1;

また

SELECT * FROM `urls` WHERE `url_md5` = MD5('http://long-phrase...') LIMIT 1;
4

1 に答える 1

2

INDEXを使用するだけで十分だと思いますが、雪の日曜日に無作法な気分で書かれた理由は次のとおりです。

データベースは、その行を次々にファイルに保存します。

 id url          name       descr         visited
  1 http://...   somewhere  i like it     2013-01-01
  2 http://...   wherever   i dislike it  2013-01-02
  ...

このデータは、おおよそ次のようにディスク上にあります。

 [s:35:http://...s:9:somewhere...][s:45:http://...s:9:wherever...][...]

たくさんのバイト、たくさんあります。DBに特定の用語を検索するように依頼した場合、DBはファイルをスキャンして「行」をスキャンし、検索用語を適用する必要があります。100万行あるとすると、DBは100万行をスキャンする必要があります。行の「url」フィールドを検索するとします。また、文字列を短縮(または拡張、「http://goo.gl/P0Gwz」のmd5を実行)したため、「検索」が簡単になったとします。100万行を検索する必要があります。

一方、行の順序付きリストを検索できれば、処理速度は大幅に向上します。したがって、DBが、行を挿入した時点ではなく、「url」フィールドで並べ替えられた行を格納するようになったとします。これで、新しい行を挿入するとすぐに、DBはディスクに格納されているすべてのバイトを並べ替える必要があります。cozの場合、検索ははるかに高速になりましたが、INSERT操作ははるかに遅くなります。そして忘れないでください:明日は「descr」フィールドを検索したいと思います。今何?ファイル全体を並べ替えますか?ファイルのコピーを2つ保持しますか?

より良いアプローチは、「行」を見つける場所への参照を含む順序付きリストであるレジスターを使用することです。そのアイデアは、実際の図書館と同じくらい古くからあります。本を次々に棚に置き、番号を付けて、リストを作成します。著者名、発行年、タイトルなどで並べ替えます。著者を検索したい著者登録を選択し、binary-search-like-approachを介して名前をスキャンし(人が賢い場合)、本の番号を取得し、棚に行き、すぐに本をピックアップします。

その「レジスタ」は「INDEX」とも呼ばれます。ディスク上の参照された行の位置への参照の順序付きリスト:

 [s:35:http://...s:9:somewhere...][s:45:http://...s:9:wherever...][...]
       ^                               ^                           ^
       |                               |                           |
       |                               |                           |
 i1   -------------------------------- ^                           |
 i2   ------------------------------------------------------------------>
 i3   -^                                                           |
 i100 -------------------------------------------------------------^

たとえば、i50検索語が一致するかどうかを確認できるようになりました。インデックス関数が50より大きいものを指している場合は、次のラウンドでi75をチェックし、50より小さい場合は、i25をチェックします。

数字を表示するには:100万行の場合、スキャンする必要のある「url」フィールドを検索します。

  • 最悪の場合、URLを見つけるための100万行(「ここにはありません」)。
  • 平均で50万行(「均等配分」)。
  • log2(10 ^ 6)== 20は、最悪の場合、INDEXのURLに対してチェックします。
  • log2(10 ^ 6)-1==19は平均してINDEXのURLに対してチェックします。

そして明日は200万行になります。ここで、INDEXを使用せずに200万行以上をスキャンする必要があり、正しいレコードを見つけるか、何も見つけないようにするには、最大20回までスキャンする必要があります。数百万の文字列比較と20。INDEXの使用がどれほど大きな影響を与えるかがわかります。

ここでトピックについてもっと読む:

于 2013-01-20T09:06:09.157 に答える