0

笔记:

所以正如我所想,真正的问题是因为我用于标记的 IN 子句。更改文本搜索的查询部分并没有太大帮助。知道如何改进查询吗?

查询在服务器上运行时耗时过长。这里 Partha S 是用户输入的搜索项。表contacts包含个人信息,tags包含类别名称和id;并且contacts2tags 表包含contactid 和tagid,其值分别类似于contacts 和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 运算符以进行精确搜索,并在后一种情况下使用 MATCH(..) AGAINST(..) 而不是 LIKE 。虽然第一个更改确实提高了一点性能,但使用 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

一种优化是,在这种exact情况下,您不需要使用 LIKE(您应该只将它与通配符 - % 一起使用)。

您可以做的另一件事是让事情变得更快,将索引添加到您将要搜索的文件中。

此外,只有当您使用 MyISSAM 作为存储引擎(用于该表)时,您才能像这样使用全文搜索

SELECT * FROM normalWHERE MATCH(title, body) AGAINST ('Queried_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

不仅仅是所有的LIKEs,还有ORs。即使对于使用 的条件LIKE,也会使用索引。因此,为了加快查询速度,您可以为每个表创建一个非常大的索引,该索引结合了您正在搜索的所有字段。

但是如果你真的想建立一个搜索引擎,你可能需要考虑使用 Sphinx 或 ElasticSearch 来代替 MySQL 像这样的怪物查询。

于 2014-01-16T06:24:36.697 回答
0

您可能想看看MySQLmatch()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 回答