У меня есть троичные отношения, которые называются ternary
, например:
id_Offer - id_Profile - id_Skill
1 - 1 - 1
1 - 2 - 1
[and so on, there would be more registers for each id_Offer from Offer but I want to limit the example]
Таблица профиля выглядит примерно так (profile_interest - это таблица, которая устанавливает связь между профилем и интересом, вот и все):
id_Profile - profile_name
1 - profile-1
2 - profile-2
3 - profile-3
Поэтому, когда я делаю следующий запрос, чем больше я добавляю предложений OR, тем хуже выполняется запрос, начиная с ~ 0,1-0,2 секунды, что я получаю для любого другого запроса, который я делаю,и до 1,5 секунд.
SELECT DISTINCT ternary_table.id_profile, COUNT(distinct profile_interest.id_interest) as matching
FROM ternary_table INNER JOIN profile ON ternary_table.id_profile=profile.id_profile
INNER JOIN profile_interest ON profile.id_profile=profile_interest.id_profile
WHERE profile_interest.id_interest= '1'
OR profile_interest.id_interest = '2'
OR profile_interest.id_interest = '3'
OR profile_interest.id_interest = '14'
OR profile_interest.id_interest = '15'
OR profile_interest.id_interest = '16'
GROUP BY(ternary_table.id_profile)
ORDER BY matching DESC;
Я пытался сделать поле profile_interest.id_interest индексированным столбцом с:
CREATE INDEX filter_interest ON profile_interest(id_interest );
Без каких-либо улучшений.База данных весит меньше гигабайта, это очень маленькая база данных с ~ 15 таблицами, поэтому я хотел бы знать, есть ли способ сократить задержку запроса.
Редактировать: чтобы добавить больше информации, причинаМеня это беспокоит, потому что единственная цель этих данных - подключиться к API, поэтому любая задержка в SQL будет задерживать каждый вызов этих данных.
Edit1: добавлен вывод EXPLAIN и удалены первые отличия, так как в этом нет необходимости
+----+-------------+---------------------+------------+--------+------------------------------------------------+------------+---------+------------------------------------+------+----------+-----------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------------------+------------+--------+------------------------------------------------+------------+---------+------------------------------------+------+----------+-----------------------------------------------------------+
| 1 | SIMPLE | profile_interest | NULL | range | PRIMARY,id_interest,filter_interest | id_interest | 202 | NULL | 40 | 100.00 | Using where; Using index; Using temporary; Using filesort |
| 1 | SIMPLE | perfil | NULL | eq_ref | PRIMARY | PRIMARY | 202 | BBDD.profile_interest.id_perfil | 1 | 100.00 | Using index |
| 1 | SIMPLE | oferta_skill_perfil | NULL | ref | PRIMARY,id_skill,id_perfil | id_perfil | 202 | BBDD.profile_interest.id_perfil | 4609 | 100.00 | Using index |
+----+-------------+---------------------+------------+--------+------------------------------------------------+------------+---------+------------------------------------+------+----------+-----------------------------------------------------------+
Edit 2: добавлено создание таблицы для каждого запроса
SET FOREIGN_KEY_CHECKS=1;
CREATE TABLE profile (
id_profile VARCHAR(200) NOT NULL,
name_profile VARCHAR(200),
type_profile VARCHAR(200),
PRIMARY KEY (id_profile)
);
CREATE TABLE ternary (
id_oferta VARCHAR(200) NOT NULL,
id_skill VARCHAR(200) NOT NULL,
id_profile VARCHAR(200) NOT NULL,
ranking_skill DOUBLE NOT NULL,
PRIMARY KEY (id_oferta, id_skill, id_profile),
FOREIGN KEY (id_oferta) REFERENCES oferta(id_oferta),
FOREIGN KEY (id_skill) REFERENCES skill(id_skill),
FOREIGN KEY (id_profile) REFERENCES profile(id_profile)
);
CREATE TABLE interest (
id_interest VARCHAR(200) NOT NULL,
name_interes VARCHAR(200),
PRIMARY KEY (id_interest)
);
CREATE TABLE profile_interest (
id_profile VARCHAR(200) NOT NULL,
id_interest VARCHAR(200) NOT NULL,
PRIMARY KEY (id_profile, id_interest),
FOREIGN KEY (id_profile) REFERENCES profile(id_profile),
FOREIGN KEY (id_interest) REFERENCES interes(id_interest)
);