10

このクエリ ("jack" ではなく別の名前) は、スロー クエリ ログで何度も発生します。なんで?

Users テーブルには多くのフィールド (私が選択したこれらの 3 つ以外) と約 40.000 行があります。

select name,username,id from Users where ( name REGEXP '[[:<:]]jack[[:>:]]' ) or ( username REGEXP '[[:<:]]jack[[:>:]]' ) order by name limit 0,5;

idプライマリで自動インクリメントです。
name索引があります。
usernameユニークなインデックスを持っています。

3秒かかる時もある!MySQL の選択について説明すると、次のようになります。

select type: SIMPLE
table: Users
type: index
possible keys: NULL
key: name
key len: 452
ref: NULL
rows: 5
extra: Using where

これは私ができる最善のことですか?何を修正できますか?

4

3 に答える 3

22

正規表現スタイルのWHERE句を使用する必要がある場合は、クエリが遅いという問題に悩まされることは間違いありません。正規表現スタイルの検索を機能させるために、MySQL は名前列のすべての値を正規表現と比較する必要があります。また、ユーザー名列も確認することで、クエリは問題を 2 倍にしました。

これは、MySQL がインデックスを利用できないことを意味します。これは、すべての DBMS が大きなテーブルのクエリを高速化する方法です。

いくつか試してみることができます。それらのすべてには、REGEXP に別れを告げることが含まれます。

1つはこれです:

WHERE name LIKE CONCAT('jack', '%') OR username LIKE CONCAT('jack', '%')

名前とユーザー名の列にインデックスを作成すると、かなり高速になります。「jack」で始まるすべての名前/ユーザー名が検索されます。注意してください

WHERE name LIKE CONCAT('%','jack') /* SLOW!!! */

「jack」で終わる名前を探しますが、正規表現スタイルの検索のように遅くなります。

もう 1 つできることは、アプリケーションが名前またはユーザー名の一部を検索できるようにする必要がある理由を理解することです。アプリケーションからこの機能を削除するか、それを処理するためのより良い方法を見つけることができます。

考えられるより良い方法:

  1. ユーザーに名前を名と姓のフィールドに分割し、別々に検索するように依頼します。
  2. ユーザーが必要な場合にのみ使用される別の「すべてのユーザーを検索」機能を作成して、低速な正規表現スタイルのクエリの頻度を減らします。
  3. ある種の前処理プログラムを使用して、自分で名前を別の名前と単語のテーブルに分割します。正規表現なしで名前と単語のテーブルを検索します。
  4. この機能に MySQL 全文検索を使用する方法を理解してください。

これらはすべて、プログラミング作業を伴います。

于 2012-09-07T13:28:48.003 に答える
-4

「いいね」を先頭に追加

から

SELECT cat_ID, categoryName FROM category WHERE cat_ID REGEXP '^15-64-8$' ORDER BY categoryName

SELECT cat_ID, categoryName FROM category WHERE cat_ID LIKE '15-64-8%' and cat_ID REGEXP '^15-64-8$' ORDER BY categoryName

もちろん、これは、何から始まるか知っているフレーズを検索する場合にのみ機能します。それ以外の場合は、全文索引が解決策になります。

于 2013-02-07T18:42:13.197 に答える