3

コース検索エンジンを使用していますが、検索しようとすると、検索結果が表示されるまでに時間がかかりすぎます。ここで検索してみることができます

http://76.12.87.164/cpd/testperformance.cfm

そのページでは、データベースのテーブルとインデックスも表示されます (存在する場合)。

私はストアド プロシージャを使用していません。クエリは Coldfusion を使用してインライン化されています。

いくつかのインデックスを作成する必要があると思いますが、どの種類 (クラスター化、非クラスター化) で、どの列にあるのかわかりません。

ありがとう

4

5 に答える 5

2

WHERE句に表示される列にインデックスを作成する必要があります。この規則にはいくつかの例外があります。

  • 列に一意の値が 1 つまたは 2 つしかない場合 (これの標準的な例は「性別」です。可能な値は「男性」と「女性」のみであり、ここではインデックスの意味がありません)。一般に、処理する必要がある行をかなりの数だけ制限できるインデックスが必要です (たとえば、検索スペースを 50% 削減するだけのインデックスは価値がありませんが、99% 削減するインデックスは価値がありません)。 %) です。
  • 検索している場合x LIKE '%something'、インデックスの意味はありません。インデックスが行の特定の順序xを指定していると考える場合、「%something」を検索する場合の並べ替えは役に立ちません。とにかくすべての行をスキャンする必要があります。

では、「キーワード「会計」」で検索している場合を見てみましょう。結果ページによると、これが生成する SQL は次のとおりです。

SELECT
  *
FROM (
  SELECT TOP 10
    ROW_NUMBER() OVER (ORDER BY sq.name) AS Row,
    sq.*
  FROM (
    SELECT
      c.*,
      p.providername,
      p.school,
      p.website,
      p.type
    FROM
      cpd_COURSES c, cpd_PROVIDERS p
    WHERE
      c.providerid = p.providerid AND
      c.activatedYN = 'Y' AND
      (
        c.name like '%accounting%' OR
        c.title like '%accounting%' OR
        c.keywords like '%accounting%'
      )
  ) sq
) AS temp
WHERE
  Row >= 1 AND Row <= 10 

この場合、それcpd_COURSES.provideridは外部キーであると仮定します。この場合cpd_PROVIDERS.providerid、インデックスは必要ありません。既にインデックスがあるためです。

さらに、このactivatedYN列は T/F 列であり、(可能な値を 50% だけに制限するという上記のルールに従って) T/F 列にもインデックスを付けるべきではありません。

最後に、x LIKE '%accounting%'クエリで検索するため、名前、タイトル、またはキーワードのインデックスも必要ありません。使用されることはないためです。

したがって、この場合に行う必要がある主なことは、 がcpd_COURSES.providerid実際の外部キーであることを確認することですcpd_PROVIDERS.providerid

SQL Server 固有

SQL Server を使用しているため、Management Studio には、インデックスを配置する必要がある場所を決定するのに役立つツールが多数用意されています。「インデックス チューニング ウィザード」を使用すると、実際には、パフォーマンスを向上させる方法を教えてくれるのが非常に優れています。クエリをカットアンドペーストするだけで、追加するインデックスの推奨事項が返されます。

追加するインデックスには少し注意する必要があります。インデックスが多いほど、INSERTs とUPDATEs が遅くなるためです。そのため、インデックスを統合する必要がある場合や、パフォーマンスが十分に向上しない場合は完全に無視する必要がある場合があります。ある程度の判断は必要です。

于 2010-06-15T00:58:25.790 に答える
1

これは実際のライブ データベース データですか? 52,000 レコードは、SQL 2005 で処理できるテーブルとしては、比較的小さいテーブルです。

SQL サーバーにどれだけの RAM が割り当てられているか、またはデータベースがどのような種類のディスク上にあるのだろうか。IDE や SATA ハード ディスクでさえ、15K RPM SAS ディスクと同じパフォーマンスを提供することはできません。頻繁にアクセスされるデータの大部分をキャッシュするのに十分な RAM があればよいでしょう。

そうは言っても、" (c.name like '%accounting%' OR c.title like '%accounting%' OR c.keywords like '%accounting%') " 節に問題があると思います。

"courseid" と "keyword" の 2 つの列 (最長のキーワードには varchar(24) で十分でしょうか?) と、courseid+keyword の複合クラスター化インデックスを使用して、別の Course_Keywords テーブルを作成できますか?

次に、UI をさらに使いやすくするために、ユーザーがキーワード入力フィールドに単語を入力したときに、AJAX を使用してキーワードの検証とオートコンプリートを適用します。これにより、正確なキーワードを検索するという舞台裏の利点が得られ、LIKE 演算子によるパターン マッチングの必要がなくなります...

于 2010-06-15T00:58:41.780 に答える
0

IN ステートメントを EXISTS クエリに変更して、郵便番号検索のパフォーマンスが向上するかどうかを確認します。私の経験では、IN ステートメントは小さなリストではうまく機能しますが、リストが大きくなるほど、クエリ エンジンが最初に実行されたインスタンスで特定の値の検索を停止するため、EXISTS のパフォーマンスが向上します。

<CFIF zipcodes is not "">
    EXISTS (
        SELECT zipcode
        FROM cpd_CODES_ZIPCODES
        WHERE zipcode = p.zipcode
            AND 3963 * (ACOS((SIN(#getzipcodeinfo.latitude#/57.2958) * SIN(latitude/57.2958)) +
            (COS(#getzipcodeinfo.latitude#/57.2958) * COS(latitude/57.2958) *
            COS(longitude/57.2958 - #getzipcodeinfo.longitude#/57.2958)))) <= #radius#
    )
</CFIF>
于 2010-06-15T18:50:02.110 に答える
0

CF9を使用していますか?%xxx%?の代わりに Solr 全文検索を使用してみてください。

于 2010-06-15T00:59:52.900 に答える
0

検索するフィールドにインデックスを作成する必要があります。インデックスは、インデックス付きフィールドによって事前に並べ替えられたレコードの二次リストです。

昔ながらの印刷されたイエロー ページを考えてみてください。人を姓で検索したい場合、電話帳は既にそのように並べ替えられています。姓はクラスタ化されたインデックス フィールドです。Jennifer という名前の人や電話番号 867-5309 の人の電話番号を見つけたい場合は、すべてのエントリを検索する必要があり、長い時間がかかります。その人がリストされている電話帳のページと一緒に、すべての電話番号または名前が順番にリストされた索引が後ろにあると、はるかに高速になります。これらは、非クラスター化インデックスになります。

于 2010-06-15T01:12:27.660 に答える