· 8 years ago · Jan 10, 2018, 03:08 PM
1ИÑпользуетÑÑ MySQL.
2Тип таблицы ÑÑылок - myisam, Ð´Ð»Ñ ÑƒÐ»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñти (Ñ‚.е. идет ÑÐµÑ€ÑŒÐµÐ·Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ в таблицу). Транзакционный движок Ð´Ð»Ñ Ñ‚Ð°ÐºÐ¾Ð¹ задачи не нужен, поÑтому не думаю, что Ñто проблема.
3explain показывает иÑпользование индекÑов (и cons) 1 к 1, что еÑть отличный результат.
4МинуÑом Ñтого Ñ€ÐµÑˆÐµÐ½Ð¸Ñ ÑвлÑетÑÑ Ñам Ð¸Ð½Ð´ÐµÐºÑ - на каждую запиÑÑŒ он будет переÑтраиватьÑÑ, что веÑьма Ð´Ð¾Ñ€Ð¾Ð³Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ.
5
6ЕÑть альтернативные подходы к решению задачи - иÑпользовать nosql решениÑ, иÑпользовать таблицу без индекÑов Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи произошедшего ÑобытиÑ, а затем в фоне (!) проводить агрегацию и Ð¿ÐµÑ€ÐµÐ½Ð¾Ñ Ð² таблицы Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð¾Ðº\кубы\etc.
7
8Можно чаÑть раÑÑчетов возложить на приложение (Ñ…Ð¾Ñ‚Ñ Ñ Ð±Ñ‹ так не делал).
9
10
11
12DROP TABLE IF EXISTS `company`;
13DROP TABLE IF EXISTS `company_event`;
14DROP TABLE IF EXISTS `company_event_reference`;
15
16CREATE TABLE `company` (
17 `company_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
18 `name` VARCHAR(100) NOT NULL,
19
20 PRIMARY KEY (`company_id`)
21) ENGINE=INNODB DEFAULT CHARSET=utf8;
22
23CREATE TABLE `company_event` (
24 `company_event_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
25 `name` VARCHAR(100) NOT NULL,
26
27 PRIMARY KEY (`company_event_id`)
28) ENGINE=INNODB DEFAULT CHARSET=utf8;
29
30CREATE TABLE `company_event_reference` (
31 `company_event_reference_id` INT(10) UNSIGNED NOT NULL,
32 `company_id` INT(10) UNSIGNED NOT NULL,
33 `company_event_id` INT(10) UNSIGNED NOT NULL,
34 `create_time` DATETIME NOT NULL,
35
36 PRIMARY KEY (`company_event_reference_id`),
37 KEY (`company_id`, `company_event_id`, `create_time`)
38) ENGINE=MYISAM DEFAULT CHARSET=utf8;
39
40
41INSERT INTO company (company_id, `name`) VALUES (1, 'comp1');
42INSERT INTO company (company_id, `name`) VALUES (2, 'comp2');
43INSERT INTO company (company_id, `name`) VALUES (3, 'comp3');
44
45INSERT INTO company_event (company_event_id, `name`) VALUES (1, 'event1');
46INSERT INTO company_event (company_event_id, `name`) VALUES (2, 'event2');
47INSERT INTO company_event (company_event_id, `name`) VALUES (3, 'event3');
48INSERT INTO company_event (company_event_id, `name`) VALUES (4, 'event4');
49INSERT INTO company_event (company_event_id, `name`) VALUES (5, 'event5');
50
51INSERT INTO company_event_reference (company_event_reference_id, company_id, company_event_id, create_time)
52VALUES (1, 1, 1, '2017-01-01');
53INSERT INTO company_event_reference (company_event_reference_id, company_id, company_event_id, create_time)
54VALUES (2, 1, 1, '2017-01-01');
55
56INSERT INTO company_event_reference (company_event_reference_id, company_id, company_event_id, create_time)
57VALUES (3, 1, 2, '2017-01-01');
58INSERT INTO company_event_reference (company_event_reference_id, company_id, company_event_id, create_time)
59VALUES (4, 1, 1, '2017-01-02');
60
61
62INSERT INTO company_event_reference (company_event_reference_id, company_id, company_event_id, create_time)
63VALUES (5, 2, 1, '2017-01-01');
64INSERT INTO company_event_reference (company_event_reference_id, company_id, company_event_id, create_time)
65VALUES (6, 2, 1, '2017-01-02');
66
67INSERT INTO company_event_reference (company_event_reference_id, company_id, company_event_id, create_time)
68VALUES (7, 3, 3, '2017-01-03');
69
70EXPLAIN SELECT *
71FROM company_event_reference cer
72INNER JOIN company c ON c.company_id = cer.company_id
73INNER JOIN company_event ce ON ce.company_event_id = cer.company_event_id
74WHERE cer.company_id = 1 AND cer.company_event_id = 1 AND cer.create_time = '2017-01-02';
75
76EXPLAIN SELECT cer.create_time, COUNT(*)
77FROM company_event_reference cer
78INNER JOIN company c ON c.company_id = cer.company_id
79INNER JOIN company_event ce ON ce.company_event_id = cer.company_event_id
80WHERE cer.company_id = 1 AND cer.company_event_id = 1
81GROUP BY cer.create_time;