在查询优化方面需要帮助
need help in query optimization
我有以下查询需要很长时间才能执行,因为它有 OR opeartion.Here 机构 59958 是一个全球机构。它本身可以有统计数据,它的 children 也可以有统计数据;所以 'parentinstitutionid' 对于 59958 或 institutionid 59958 我们需要使用数据 for.so 我正在使用 OR opeartor。
select date(SUBDATE(m.timestamp, INTERVAL (day(m.timestamp) -1) day)) as month,
count(*) as c,
sum(case when a.streamid = 5 then 1 else 0 end) as education,
sum(case when a.streamid in(7, 1) then 1 else 0 end) as research,
sum(case when searchterms <> '' then 1 else 0 end) as search
from stats_to_institution as s
join masterstats_innodb as m on s.statid = m.id
left join articles as a on (a.productid >= 49 and a.productid = m.article)
where m.timestamp >= '2022-01-01'
and (s.institutionid = 59958 or s.institutionid in ( select institutionid from institutions where parentinstitutionid = 59958))
group by month;
以下情况需要时间
(s.institutionid = 59958 或 s.institutionid in (select institutionid from institutions where parentinstitutionid = 59958))
我无法使用 5.6 上的 CTE version.Is 是否有任何其他方法可以修改上述条件以获得良好的性能?。
如果我删除 s.institutionid = 59958 它只需要 5 秒到 运行 因为它不会有 OR 运算符。
对此有什么建议吗?
table结构如下
CREATE TABLE `institutions` (
`InstitutionID` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(200) DEFAULT NULL,
`Approved` tinyint(1) NOT NULL DEFAULT '0',
`DateAdded` datetime DEFAULT CURRENT_TIMESTAMP,
`IsAcademic` tinyint(1) DEFAULT NULL,
`IsIndustry` tinyint(1) DEFAULT NULL,
`LogoFile` varchar(50) DEFAULT NULL,
`NotifyLibEveryXRequests` int(11) DEFAULT NULL,
`IsParentInstitution` int(1) NOT NULL DEFAULT '0',
`ParentInstitutionID` int(11) DEFAULT NULL,
PRIMARY KEY (`InstitutionID`),
KEY `Institutions_Name` (`Name`),
KEY `ParentInstitutionID` (`ParentInstitutionID`),
FULLTEXT KEY `Name` (`Name`)
) ;
CREATE TABLE `masterstats_innodb` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`page` text COLLATE utf8_unicode_ci NOT NULL,
`video` int(11) NOT NULL,
`language` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`referrer` text COLLATE utf8_unicode_ci NOT NULL,
`joveuser` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`timestamp` date NOT NULL DEFAULT '0000-00-00',
PRIMARY KEY (`id`,`timestamp`),
KEY `joveuser` (`joveuser`),
KEY `institutionid` (`institutionid`),
KEY `timestamp` (`timestamp`),
KEY `idx__video_timestamp` (`video`,`timestamp`)
) ;
CREATE TABLE `stats_to_institution` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`statid` int(11) NOT NULL,
`institutionid` int(11) NOT NULL,
PRIMARY KEY (`id`,`institutionid`),
UNIQUE KEY `statid_2` (`statid`,`institutionid`),
KEY `statid` (`statid`),
KEY `institutionid` (`institutionid`)
) ;
CREATE TABLE `articles` (
`ProductID` int(11) NOT NULL,
`Name` varchar(1000) DEFAULT NULL,
`Tags` varchar(1000) NOT NULL,
`D` varchar(2000) DEFAULT NULL,
`Active` tinyint(1) DEFAULT NULL,
`UserID` int(11) DEFAULT NULL,
`DateAdded` datetime DEFAULT NULL,
`Detail_Abstract` text,
`StreamID` int(11) DEFAULT NULL COMMENT '-1 = Errata, 1= Article, 2= Advertisment, 3 = Editorial, 4= Junk, 5=SE',
`DatePublished` datetime DEFAULT NULL,
`AccessType` int(11) DEFAULT NULL COMMENT '-1=Unpublished, 0=Closed, 1=Free, 2=Open, 3 = Open UK',
`Rep_Results` text,
`Stage` int(11) DEFAULT NULL,
`SectionID` int(11) DEFAULT NULL,
PRIMARY KEY (`ProductID`),
KEY `Articles_StreamID_Active_DatePublished` (`StreamID`,`Active`,`DatePublished`),
KEY `articles_idx_sectionid` (`SectionID`),
FULLTEXT KEY `DetailAbstractTest` (`Detail_Abstract`,`Name`),
FULLTEXT KEY `Materials` (`Materials`),
FULLTEXT KEY `title` (`Name`)
);
解释结果
+----+-------------+--------------+--------+------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------+-----------------+----------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+--------+------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------+-----------------+----------+----------------------------------------------+
| 1 | PRIMARY | m | ALL | PRIMARY,timestamp_video,joveuser,institutionid,video_institutionid,user_id,ip_binary,time_on_page,Article,timestamp,idx__video_timestamp | NULL | NULL | NULL | 19653526 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | a | eq_ref | PRIMARY | PRIMARY | 4 | stats.m.Article | 1 | Using where |
| 1 | PRIMARY | s | ref | statid_2,statid,institutionid | statid_2 | 4 | stats.m.id | 1 | Using where; Using index |
| 2 | SUBQUERY | institutions | ref | PRIMARY,ParentInstitutionID | ParentInstitutionID | 5 | const | 173 | Using index |
+----+-------------+--------------+--------+------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------+-----------------+----------+----------------------------------------------+
没有CTE,加入怎么样?
select date(SUBDATE(m.timestamp, INTERVAL (day(m.timestamp) -1) day)) as month,
count(*) as c,
sum(case when a.streamid = 5 then 1 else 0 end) as education,
sum(case when a.streamid in(7, 1) then 1 else 0 end) as research,
sum(case when searchterms <> '' then 1 else 0 end) as search
from stats_to_institution as s
join (select institutionid
from institutions
where parentinstitutionid = 59958
union all select 59998
) x on x.institutionid = s.institutionid
join masterstats_innodb as m on s.statid = m.id
left join articles as a on (a.productid >= 49 and a.productid = m.article)
where m.timestamp >= '2022-01-01'
group by month;
我有以下查询需要很长时间才能执行,因为它有 OR opeartion.Here 机构 59958 是一个全球机构。它本身可以有统计数据,它的 children 也可以有统计数据;所以 'parentinstitutionid' 对于 59958 或 institutionid 59958 我们需要使用数据 for.so 我正在使用 OR opeartor。
select date(SUBDATE(m.timestamp, INTERVAL (day(m.timestamp) -1) day)) as month,
count(*) as c,
sum(case when a.streamid = 5 then 1 else 0 end) as education,
sum(case when a.streamid in(7, 1) then 1 else 0 end) as research,
sum(case when searchterms <> '' then 1 else 0 end) as search
from stats_to_institution as s
join masterstats_innodb as m on s.statid = m.id
left join articles as a on (a.productid >= 49 and a.productid = m.article)
where m.timestamp >= '2022-01-01'
and (s.institutionid = 59958 or s.institutionid in ( select institutionid from institutions where parentinstitutionid = 59958))
group by month;
以下情况需要时间 (s.institutionid = 59958 或 s.institutionid in (select institutionid from institutions where parentinstitutionid = 59958))
我无法使用 5.6 上的 CTE version.Is 是否有任何其他方法可以修改上述条件以获得良好的性能?。 如果我删除 s.institutionid = 59958 它只需要 5 秒到 运行 因为它不会有 OR 运算符。
对此有什么建议吗?
table结构如下
CREATE TABLE `institutions` (
`InstitutionID` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(200) DEFAULT NULL,
`Approved` tinyint(1) NOT NULL DEFAULT '0',
`DateAdded` datetime DEFAULT CURRENT_TIMESTAMP,
`IsAcademic` tinyint(1) DEFAULT NULL,
`IsIndustry` tinyint(1) DEFAULT NULL,
`LogoFile` varchar(50) DEFAULT NULL,
`NotifyLibEveryXRequests` int(11) DEFAULT NULL,
`IsParentInstitution` int(1) NOT NULL DEFAULT '0',
`ParentInstitutionID` int(11) DEFAULT NULL,
PRIMARY KEY (`InstitutionID`),
KEY `Institutions_Name` (`Name`),
KEY `ParentInstitutionID` (`ParentInstitutionID`),
FULLTEXT KEY `Name` (`Name`)
) ;
CREATE TABLE `masterstats_innodb` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`page` text COLLATE utf8_unicode_ci NOT NULL,
`video` int(11) NOT NULL,
`language` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`referrer` text COLLATE utf8_unicode_ci NOT NULL,
`joveuser` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`timestamp` date NOT NULL DEFAULT '0000-00-00',
PRIMARY KEY (`id`,`timestamp`),
KEY `joveuser` (`joveuser`),
KEY `institutionid` (`institutionid`),
KEY `timestamp` (`timestamp`),
KEY `idx__video_timestamp` (`video`,`timestamp`)
) ;
CREATE TABLE `stats_to_institution` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`statid` int(11) NOT NULL,
`institutionid` int(11) NOT NULL,
PRIMARY KEY (`id`,`institutionid`),
UNIQUE KEY `statid_2` (`statid`,`institutionid`),
KEY `statid` (`statid`),
KEY `institutionid` (`institutionid`)
) ;
CREATE TABLE `articles` (
`ProductID` int(11) NOT NULL,
`Name` varchar(1000) DEFAULT NULL,
`Tags` varchar(1000) NOT NULL,
`D` varchar(2000) DEFAULT NULL,
`Active` tinyint(1) DEFAULT NULL,
`UserID` int(11) DEFAULT NULL,
`DateAdded` datetime DEFAULT NULL,
`Detail_Abstract` text,
`StreamID` int(11) DEFAULT NULL COMMENT '-1 = Errata, 1= Article, 2= Advertisment, 3 = Editorial, 4= Junk, 5=SE',
`DatePublished` datetime DEFAULT NULL,
`AccessType` int(11) DEFAULT NULL COMMENT '-1=Unpublished, 0=Closed, 1=Free, 2=Open, 3 = Open UK',
`Rep_Results` text,
`Stage` int(11) DEFAULT NULL,
`SectionID` int(11) DEFAULT NULL,
PRIMARY KEY (`ProductID`),
KEY `Articles_StreamID_Active_DatePublished` (`StreamID`,`Active`,`DatePublished`),
KEY `articles_idx_sectionid` (`SectionID`),
FULLTEXT KEY `DetailAbstractTest` (`Detail_Abstract`,`Name`),
FULLTEXT KEY `Materials` (`Materials`),
FULLTEXT KEY `title` (`Name`)
);
解释结果
+----+-------------+--------------+--------+------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------+-----------------+----------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+--------+------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------+-----------------+----------+----------------------------------------------+
| 1 | PRIMARY | m | ALL | PRIMARY,timestamp_video,joveuser,institutionid,video_institutionid,user_id,ip_binary,time_on_page,Article,timestamp,idx__video_timestamp | NULL | NULL | NULL | 19653526 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | a | eq_ref | PRIMARY | PRIMARY | 4 | stats.m.Article | 1 | Using where |
| 1 | PRIMARY | s | ref | statid_2,statid,institutionid | statid_2 | 4 | stats.m.id | 1 | Using where; Using index |
| 2 | SUBQUERY | institutions | ref | PRIMARY,ParentInstitutionID | ParentInstitutionID | 5 | const | 173 | Using index |
+----+-------------+--------------+--------+------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------+-----------------+----------+----------------------------------------------+
没有CTE,加入怎么样?
select date(SUBDATE(m.timestamp, INTERVAL (day(m.timestamp) -1) day)) as month,
count(*) as c,
sum(case when a.streamid = 5 then 1 else 0 end) as education,
sum(case when a.streamid in(7, 1) then 1 else 0 end) as research,
sum(case when searchterms <> '' then 1 else 0 end) as search
from stats_to_institution as s
join (select institutionid
from institutions
where parentinstitutionid = 59958
union all select 59998
) x on x.institutionid = s.institutionid
join masterstats_innodb as m on s.statid = m.id
left join articles as a on (a.productid >= 49 and a.productid = m.article)
where m.timestamp >= '2022-01-01'
group by month;