首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL如何优化%LIKE%查询?

MySQL如何优化%LIKE%查询?
EN

Stack Overflow用户
提问于 2021-01-29 21:46:23
回答 1查看 133关注 0票数 0

正在尝试优化MySQL查询。需要优化的原因是表的增长。目前它大约有300K行,将来会更多。

表结构

代码语言:javascript
复制
CREATE TABLE `activity_log` (
  `id` int(11) UNSIGNED NOT NULL,
  `date_created` datetime NOT NULL,
  `user_id` int(11) UNSIGNED NOT NULL,
  `event_id` smallint(6) UNSIGNED NOT NULL,
  `activity_by` tinyint(4) NOT NULL DEFAULT '0' COMMENT '''0'' - by client himself; ''-1'' - by admin; other - ap_user.id;',
  `text` text NOT NULL,
  `notes` text NOT NULL,
  `ip` char(46) DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=utf8;

ALTER TABLE `activity_log`
  ADD PRIMARY KEY (`id`),
  ADD KEY `client_id` (`user_id`),
  ADD KEY `event_id` (`event_id`),
  ADD KEY `date_created` (`date_created`),
  ADD KEY `ip` (`ip`);
ALTER TABLE `activity_log` ADD FULLTEXT KEY `text` (`text`);

ALTER TABLE `activity_log`
  MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2435463;
COMMIT;

查询需要优化:

代码语言:javascript
复制
SELECT a.id,a.activity_by,a.user_id,a.date_created,
            DATE_FORMAT(a.date_created,'%e %b, %Y') as date,
            DATE_FORMAT(a.date_created,'%H:%i') as time ,
            a.text,a.notes,e.color,e.link_icon,  u.id as user_id, u.login, r.role 
                  FROM `activity_log` a
                        LEFT JOIN `ap_user` u ON a.activity_by = u.id
                        LEFT JOIN `ap_role` r ON u.role_id = r.id,
                  `activity_log_events` e
                  WHERE 1
                  AND a.event_id=e.id
                  AND a.text LIKE '%test tester%'
         ORDER BY `date_created` DESC, `id` DESC

我已经尝试将%LIKE% query替换为FULLTEXT

代码语言:javascript
复制
SELECT a.id,a.activity_by,a.user_id,a.date_created,
        DATE_FORMAT(a.date_created,'%e %b, %Y') as date,
        DATE_FORMAT(a.date_created,'%H:%i') as time ,
        a.text,a.notes,e.color,e.link_icon,  u.id as user_id, u.login, r.role 
              FROM `activity_log` a
                    LEFT JOIN `ap_user` u ON a.activity_by = u.id
                    LEFT JOIN `ap_role` r ON u.role_id = r.id,
              `activity_log_events` e
              WHERE 1
              AND a.event_id=e.id
    AND MATCH (a.text) AGAINST ('test tester*' IN BOOLEAN MODE) ORDER BY `date_created` DESC, `id` DESC 

在结束时,如果此信息很重要,则此查询将具有DataProvider和分页的LIMIT 15近似值。

所以我添加了FULLTEXT index,并在这个表中放置了假数据,它有大约一百万行。

奇怪的是,like查询为100万行的表提供了1300个结果,而MATCH查询为同一个表提供了200_000。

首先,我认为这是因为表中包含相同的行,因为我复制了它们以进行测试。这是可能的吗?由于这个原因,FULLTEXT搜索非常慢,并且like搜索给出了不公平的结果- 1k而不是200k。这是一个特定表,无论如何都会包含许多类似的单词,如名称和标准短语,如“已添加”或“已删除”。

如何优化这个%like%查询?有没有可能没有FULLTEXT呢?如果没有-我到底在FULLTEXT查询方面做错了什么?

谢谢你的帮助。

EN

回答 1

Stack Overflow用户

发布于 2021-01-30 07:45:23

ORDER BY是模棱两可的;我很惊讶它没有给您一个语法错误。有两个带有id的表。

有没有使用Aria而不是InnoDB的原因?

考虑更改为

代码语言:javascript
复制
('+test +tester*' IN BOOLEAN MODE)

还要考虑一下

代码语言:javascript
复制
('+"test tester*"' IN BOOLEAN MODE)

并且,要与LIKE进行复核

代码语言:javascript
复制
MATCH(...) AGAINST(...)
AND text LIKE "..."

最后一个建议处理一些情况,在这种情况下,全文将有效地找到“单词”,然后LIKE确保它们在一起。例如为了避免匹配"test or tester“(因为中间的单词)。或者“詹姆斯·史密斯和鲍勃·多伊尔”

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65955678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档