繁体   English   中英

MySQL 如何优化%LIKE% 查询?

[英]MySQL how to optimize %LIKE% query?

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

表结构

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;

查询需要优化:

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

我已经尝试过用 FULLTEXT 替换 %LIKE% 查询

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 

最后,如果此信息很重要,此查询将有其LIMIT 15大约用于 DataProvider 和分页。

所以我添加了FULLTEXT index并将假数据放入该表中,它有大约 100 万行。

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

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

如何优化这个%like%查询? 没有FULLTEXT可能吗? 如果不是 - 我在FULLTEXT查询中到底做错了什么?

谢谢你的帮助。

ORDER BY不明确; 我很惊讶它没有给你一个语法错误。 有两个带有id的表。

是否有理由使用 Aria 而不是 InnoDB?

考虑改为

('+test +tester*' IN BOOLEAN MODE)

还考虑

('+"test tester*"' IN BOOLEAN MODE)

并且,用LIKE仔细检查:

MATCH(...) AGAINST(...)
AND text LIKE "..."

最后一条建议处理一些情况,其中 FULLTEXT 将有效地找到“单词”,然后 LIKE 确保它们在一起。 例如,避免匹配“test or tester”(因为中间词)。 或“詹姆斯·史密斯和鲍勃·道尔”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM