Question

I have this query:

SELECT COUNT(*) AS "Other"
FROM events
JOIN triggers ON events.objectid = triggers.triggerid
WHERE events.name REGEXP "No data from SAM0056(.FTG|.REC|.LEFT|.RIGHT|.BACK), .* offline"
AND events.value = 1 
AND triggers.value = 1;

In total I need to execute 32 variants of these query depending on the REGEXP. The part "SAM0056" ranges form "SAM50" to "SAM0082". So the pattern is "No data from SAM00XX(.FTG|.REC|.LEFT|.RIGHT|.BACK), .* offline" where XX ranges from 50 to 82.

I also need to execute these query every 15 seconds. So I have a lot of select statements.

These are the DDL for events and triggers:

CREATE TABLE `events` (
  `eventid` bigint(20) unsigned NOT NULL,
  `source` int(11) NOT NULL DEFAULT '0',
  `object` int(11) NOT NULL DEFAULT '0',
  `objectid` bigint(20) unsigned NOT NULL DEFAULT '0',
  `clock` int(11) NOT NULL DEFAULT '0',
  `value` int(11) NOT NULL DEFAULT '0',
  `acknowledged` int(11) NOT NULL DEFAULT '0',
  `ns` int(11) NOT NULL DEFAULT '0',
  `name` varchar(2048) COLLATE utf8_bin NOT NULL DEFAULT '',
  `severity` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`eventid`),
  KEY `events_1` (`source`,`object`,`objectid`,`clock`),
  KEY `events_2` (`source`,`object`,`clock`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

and

CREATE TABLE `triggers` (
  `triggerid` bigint(20) unsigned NOT NULL,
  `expression` varchar(2048) COLLATE utf8_bin NOT NULL DEFAULT '',
  `description` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
  `url` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
  `status` int(11) NOT NULL DEFAULT '0',
  `value` int(11) NOT NULL DEFAULT '0',
  `priority` int(11) NOT NULL DEFAULT '0',
  `lastchange` int(11) NOT NULL DEFAULT '0',
  `comments` text COLLATE utf8_bin NOT NULL,
  `error` varchar(2048) COLLATE utf8_bin NOT NULL DEFAULT '',
  `templateid` bigint(20) unsigned DEFAULT NULL,
  `type` int(11) NOT NULL DEFAULT '0',
  `state` int(11) NOT NULL DEFAULT '0',
  `flags` int(11) NOT NULL DEFAULT '0',
  `recovery_mode` int(11) NOT NULL DEFAULT '0',
  `recovery_expression` varchar(2048) COLLATE utf8_bin NOT NULL DEFAULT '',
  `correlation_mode` int(11) NOT NULL DEFAULT '0',
  `correlation_tag` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '',
  `manual_close` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`triggerid`),
  KEY `triggers_1` (`status`),
  KEY `triggers_2` (`value`,`lastchange`),
  KEY `triggers_3` (`templateid`),
  CONSTRAINT `c_triggers_1` FOREIGN KEY (`templateid`) REFERENCES `triggers` (`triggerid`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

An explain-statement of the query shows this:

+------+-------------+----------+--------+--------------------+---------+---------+------------------------+------+-------------+
| id   | select_type | table    | type   | possible_keys      | key     | key_len | ref                    | rows | Extra       |
+------+-------------+----------+--------+--------------------+---------+---------+------------------------+------+-------------+
|    1 | SIMPLE      | events   | ALL    | NULL               | NULL    | NULL    | NULL                   | 8397 | Using where |
|    1 | SIMPLE      | triggers | eq_ref | PRIMARY,triggers_2 | PRIMARY | 8       | zabbix.events.objectid |    1 | Using where |
+------+-------------+----------+--------+--------------------+---------+---------+------------------------+------+-------------+

And an insert-statement into these 2 tables (events and triggers):

insert into events (eventid,source,object,objectid,clock,ns,value,name,severity) 
values (4985807,0,0,22281,1585805538,856070799,1,'No data from SAM0106-FTG, FortiGate offline',3)

INSERT INTO triggers (description,expression,recovery_mode,type,url,priority,comments,manual_close,status,correlation_mode,recovery_expression,correlation_tag,templateid,triggerid) 
VALUES ('CPU-Temperature to high','{29157}>35','0','0','','3','','1','0','0','','','22515','22541')

So how can I optimize these query? I use mariadb version 10.1.44 on a Ubuntu version 18.04.4.

Was it helpful?

Solution

FULLTEXT(name) and MATCH(name) AGAINST('+SAM0106' IN BOOLEAN MODE)

That will let you quickly whittle down the list of possible rows. After that, the REGEXP (or whatever) can finish the filtering.

PRIMARY KEY(triggerid) is the other index that is useful for that SELECT.

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top