My question is related to this question but it differs because date time is different for each search filter.
MYSQL/MARIADB Schema and sample data:
CREATE DATABASE IF NOT EXISTS `puzzle` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;
USE `puzzle`;
DROP TABLE IF EXISTS `event`;
CREATE TABLE `event` (
`eventId` bigint(20) NOT NULL AUTO_INCREMENT,
`sourceId` bigint(20) NOT NULL COMMENT 'think of source as camera',
`carCode` varchar(40) NOT NULL COMMENT 'ex: A',
`carNumber` varchar(40) NOT NULL COMMENT 'ex: 5849',
`createdOn` datetime DEFAULT NULL,
PRIMARY KEY (`eventId`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `event` (`eventId`, `sourceId`, `carCode`, `carNumber`, `createdOn`) VALUES
(1, 44,'A', '4456', '2016-09-20 20:24:05'),
(2, 26,'B', '26484', '2016-09-20 20:24:05'),
(3, 5,'A', '4456', '2016-09-20 20:24:06'),
(4, 3,'C', '72704', '2016-09-20 20:24:15'),
(5, 3,'D' ,'399606', '2016-09-20 20:26:15'),
(6, 5, 'A', '4456', '2016-09-20 20:27:25'),
(7, 44,'C', '72704', '2016-09-20 20:29:25'),
(8, 3,'A' ,'4456', '2016-09-20 20:30:55'),
(9, 44,'B' ,'26484', '2016-09-20 20:34:55'),
(10, 26,'B' ,'4456', '2016-09-20 20:35:15'),
(11, 3, 'C','72704', '2016-09-20 20:35:15'),
(12, 3,'D', '399606', '2016-09-20 20:44:35'),
(13, 26,'A' ,'4456', '2016-09-20 20:49:45');
Requirement:
User has two search filters.
In first search filter he says, get me all the cars that have sourceId in (44,3) for certain date and time. Suppose ( e.createdOn > '2016-09-20 20:24:00' and e.createdOn < '2016-09-20 20:35:00' )
In second search filter he says, get me all the cars that have sourceId in (26,3,5) for another date and time. Suppose ( e.createdOn > '2016-09-20 20:36:00' and e.createdOn < '2016-09-20 20:49:00' )
Now I want to get all (carNumbers, carCode) which are available in both search results.
The query need to be fast since the real table contains over 300 million records.
so far below is the maximum i could go with the query (its not even producing valid results)
select distinct e1.carNumber, e1.carCode from event e1
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (44,3) ) e3 on e1.carNumber= e3.carNumber
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (44,3) ) e4 on e1.carCode= e4.carCode
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (26,3,5) ) e5 on e1.carNumber= e5.carNumber
inner join (select e2.carNumber, e2.carCode from event e2 where e2.sourceId in (26,3,5) ) e6 on e1.carCode= e6.carCode
I wonder if SQL is able to solve this question or should I use backend coding?
MySQL / MariaDB version in use:
mariadb-5.5.50
mysql-5.5.51
The following recommendations will help you in your SQL tuning process.
You'll find 3 sections below:
ALTER TABLE `event` ADD INDEX `event_idx_carnumber_carcode_sourceid` (`carNumber`,`carCode`,`sourceId`);
SELECT
DISTINCT e1.carNumber,
e1.carCode
FROM
event e1
WHERE
(
(
(
(
1 = 1
)
AND (
1 = 1
)
)
AND (
1 = 1
)
)
AND (
1 = 1
)
)
AND (
EXISTS (
SELECT
1
FROM
event e3
INNER JOIN
event e4
INNER JOIN
event e5
INNER JOIN
event e6
WHERE
(
(
(
(
(
(
(
e1.carNumber = e3.carNumber
)
AND (
e3.sourceId IN (
44, 3
)
)
)
AND (
e1.carCode = e4.carCode
)
)
AND (
e4.sourceId IN (
44, 3
)
)
)
AND (
e1.carNumber = e5.carNumber
)
)
AND (
e5.sourceId IN (
26, 3, 5
)
)
)
AND (
e1.carCode = e6.carCode
)
)
AND (
e6.sourceId IN (
26, 3, 5
)
)
)
)