0

ノート:

私が考えたように、実際の問題は、私がタグ ID に使用している IN 句が原因です。テキスト検索のクエリの一部を変更しても、あまり役に立ちませんでした。クエリを改善する方法はありますか?

サーバーでの実行中にクエリに時間がかかりすぎます。ここで Partha S はユーザーが入力した検索項目です。テーブルの連絡先には個人情報が含まれ、タグにはカテゴリ名と ID が含まれます。また、contacts2tags テーブルには contactid と tagid が含まれており、値はそれぞれ contact と tags の id に似ています。

    SELECT *
    FROM
    (
    SELECT *,
     IF
    (
     first_name LIKE 'Partha S'
    OR last_name LIKE 'Partha S'
    OR phone_number LIKE 'Partha S'
    OR mobile_number LIKE 'Partha S'
    OR email_address LIKE 'Partha S'
    OR address LIKE 'Partha S'
    OR organization LIKE 'Partha S'
    OR other LIKE 'Partha S'
    OR sector LIKE 'Partha S'
    OR designation LIKE 'Partha S'
    OR concat ( first_name,  ' ',  last_name ) LIKE 'Partha S'
    OR concat ( last_name,  ' ',  first_name ) LIKE 'Partha S',
     1,
     0 )
     as exact,
     IF
    (
    (
     first_name LIKE '%Partha%'
    OR last_name LIKE '%Partha%'
    OR phone_number LIKE '%Partha%'
    OR mobile_number LIKE '%Partha%'
    OR email_address LIKE '%Partha%'
    OR address LIKE '%Partha%'
    OR organization LIKE '%Partha%'
    OR other LIKE '%Partha%'
    OR sector LIKE '%Partha%'
    OR designation LIKE '%Partha%' )
    AND
    (
     first_name LIKE '%S%'
    OR last_name LIKE '%S%'
    OR phone_number LIKE '%S%'
    OR mobile_number LIKE '%S%'
    OR email_address LIKE '%S%'
    OR address LIKE '%S%'
    OR organization LIKE '%S%'
    OR other LIKE '%S%'
    OR sector LIKE '%S%'
    OR designation LIKE '%S%' )
    ,
     1,
     0 )
     as normal
    FROM contacts
    WHERE id in
    (
    SELECT DISTINCT contacts.id
    from contacts INNER
    JOIN contacts2tags ON contacts.id = contacts2tags.contactid
    WHERE ( tagid in ( 178 ) ) )
     )
     d
    WHERE exact = 1
    OR normal = 1
    ORDER BY exact desc,
     last_name asc LIMIT 0,
     20

更新: 提案に従って、完全一致検索の LIKE 演算子を削除し、後者の場合は LIKE の代わりに MATCH(..) AGAINST(..) を使用しました。最初の変更でパフォーマンスが少し向上しましたが、MATCH() AGAINST() を使用しても実行時間は驚くほど変わりませんでした。更新されたクエリは次のとおりです。PS MATCH(all cols) AGAINST(search item) と MATCH(single cols) AGAINST (search item) を OR で組み合わせて使ってみました。提案してください。ありがとう

     SELECT *
    FROM
    (
    SELECT *,
     IF
    (
         first_name ='Partha S'
       OR last_name ='Partha S'
       OR phone_number ='Partha S'
       OR mobile_number ='Partha S'
       OR email_address = 'Partha S'
       OR address ='Partha S'
       OR organization ='Partha S'
       OR other ='Partha S'
       OR sector ='Partha S'
       OR designation ='Partha S'
       OR concat ( first_name,  ' ',  last_name ) ='Partha S'
       OR concat ( last_name,  ' ',  first_name ) ='Partha S',
       1,
       0 )
      as exact,
       IF
      ( match(first_name,last_name,phone_number,mobile_number,email_address,  address,organization,other,sector,designation) against( 'Partha')                 
    OR  match(first_name,last_name,phone_number,mobile_number,email_address,address,organization,other,sector,designation) against( 'S')


    ,
    1,
    0 )
     as normal
    FROM contacts
    WHERE id in
    (
    SELECT DISTINCT contacts.id
    from contacts INNER
    JOIN contacts2tags ON contacts.id = contacts2tags.contactid
    WHERE ( tagid in ( 178 ) ) )
     )
     d
    WHERE exact = 1
    OR normal = 1
    ORDER BY exact desc,
     last_name asc LIMIT 0,
      20
4

3 に答える 3

1

最適化の 1 つは、このexact場合、LIKE を使用する必要がないことです (ワイルドカード - % でのみ使用する必要があります)。

処理を高速化するためにできるもう 1 つの方法は、検索するフィールドに INDEX を追加することです。

また、(そのテーブルの) ストレージ エンジンとして MyISSAM を使用している場合にのみ、このような全文検索を使用できます。

SELECT * FROM normalWHERE MATCH(title, body) AGAINST ('Queryed_string')

first_name LIKE '%S%'
OR last_name LIKE '%S%'
OR phone_number LIKE '%S%'
OR mobile_number LIKE '%S%'
OR email_address LIKE '%S%'
OR address LIKE '%S%'
OR organization LIKE '%S%'
OR other LIKE '%S%'
OR sector LIKE '%S%'
OR designation LIKE '%S%' )

プロセス全体にほとんど価値をもたらさないようです。

お役に立てれば。

于 2014-01-16T06:45:33.317 に答える
0

MySQL の概要match()と機能を知りたいと思うかもしれません。against()

ドキュメントのサンプルコードを次に示します

mysql> CREATE TABLE articles (
    ->   id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    ->   title VARCHAR(200),
    ->   body TEXT,
    ->   FULLTEXT (title,body)
    -> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO articles (title,body) VALUES
    -> ('MySQL Tutorial','DBMS stands for DataBase ...'),
    -> ('How To Use MySQL Well','After you went through a ...'),
    -> ('Optimizing MySQL','In this tutorial we will show ...'),
    -> ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
    -> ('MySQL vs. YourSQL','In the following database comparison ...'),
    -> ('MySQL Security','When configured properly, MySQL ...');
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM articles
    -> WHERE MATCH (title,body) AGAINST ('database');
+----+-------------------+------------------------------------------+
| id | title             | body                                     |
+----+-------------------+------------------------------------------+
|  5 | MySQL vs. YourSQL | In the following database comparison ... |
|  1 | MySQL Tutorial    | DBMS stands for DataBase ...             |
+----+-------------------+------------------------------------------+
2 rows in set (0.00 sec)

ここで詳細を読む- http://dev.mysql.com/doc/refman/4.1/en/fulltext-natural-language.html

于 2014-01-16T06:30:28.113 に答える
0

それはすべてのLIKESだけでなく、SでもありORます。を使用した条件でもLIKE、インデックスが使用されます。したがって、このクエリを高速化するために、検索対象のすべてのフィールドを組み合わせた 1 つの非常に大きなインデックスをテーブルごとに作成できます。

しかし、本当に検索エンジンを構築したい場合は、このような MySQL モンスター クエリの代わりに Sphinx または ElasticSearch の使用を検討することをお勧めします。

于 2014-01-16T06:24:36.697 に答える