Trying to optimize MySQL query. The reason of needed optimization is table growth. For now it has approx 300K rows and in future it will be much more.
Table structure
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;
Query need to optimize:
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
What I already tried is to replace %LIKE% query with FULLTEXT
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
At finish this query will has its LIMIT 15
approx for DataProvider and pagination if this info is important.
So I added FULLTEXT index
and placed fake data into this table and it has ~1 million rows.
The one of the strange things is that like
query gives 1300 results for 1 million rows table and MATCH
query gives 200_000 for the same table.
First thought this is because of table contains equal rows as I duplicated them for test. Is that possible? FULLTEXT
search is very slow because of that and like
search gives unfair results - 1k instead of 200k. This is specific table that anyway will contain a lot of similar words like names and standard phrases like "has added" or "has removed".
How to optimize this %like%
query? Is it possible without FULLTEXT
? If not - what exactly am I doing wrong with FULLTEXT
query?
Thanks for any help.
The ORDER BY
is ambiguous; I'm surprised it did not give you a syntax error. There are two tables with id
.
Is there a reason for using Aria instead of InnoDB?
Consider changing to
('+test +tester*' IN BOOLEAN MODE)
Consider also
('+"test tester*"' IN BOOLEAN MODE)
And, to double check with LIKE
:
MATCH(...) AGAINST(...)
AND text LIKE "..."
This last suggestion handles some cases where FULLTEXT will efficiently find the 'words', then LIKE makes sure they are together. For example to avoid matching "test or tester" (because of the intervening word). Or "James Smith and Bob Doyle".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.