OR运算子减慢MySQL查询

时间:2019-03-15 15:57:51

标签: mysql

我有四个表,每个表通过某些字段与其他表相关:games, teams, altnames, countries

在ON子句中使用OR运算符编写此查询(请参见第6行),这会大大降低查询速度:

select ROUND(AVG(attendance)), competition, team1, countries.* from games 
LEFT JOIN (teams 
    INNER JOIN countries ON ( countries.iso3 = teams.country ) 
    LEFT JOIN altnames ON ( altnames.entityType = "team" AND altnames.season = "1011" AND altnames.entityId = teams.longName )  
) 
ON ( altnames.altValue = games.team1 OR teams.longName = games.team1 )
where games.season="1011" group by games.competition, games.team1 having AVG(attendance)>= 500 order by AVG(attendance) desc

在不使用OR(一次仅两个条件之一)的情况下,查询速度足够快:

1。

select ROUND(AVG(attendance)), competition, team1, countries.* from games 
LEFT JOIN (teams 
    INNER JOIN countries ON ( countries.iso3 = teams.country ) 
    LEFT JOIN altnames ON ( altnames.entityType = "team" AND altnames.season = "1011" AND altnames.entityId = teams.longName )  
) 
ON ( altnames.altValue = games.team1 )
where games.season="1011" group by games.competition, games.team1 having AVG(attendance)>= 500 order by AVG(attendance) desc

2。

select ROUND(AVG(attendance)), competition, team1, countries.* from games 
LEFT JOIN (teams 
    INNER JOIN countries ON ( countries.iso3 = teams.country ) 
    LEFT JOIN altnames ON ( altnames.entityType = "team" AND altnames.season = "1011" AND altnames.entityId = teams.longName )  
) 
ON ( teams.longName = games.team1 )
where games.season="1011" group by games.competition, games.team1 having AVG(attendance)>= 500 order by AVG(attendance) desc

知道为什么会这样,以及如何加快第一个查询的速度吗?


编辑:

以下是表格:

替代名称:

CREATE TABLE IF NOT EXISTS `altnames` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `entityType` enum('team','comp','logo') NOT NULL,
  `entityId` varchar(50) NOT NULL DEFAULT '0',
  `season` varchar(4) NOT NULL DEFAULT '0',
  `altValue` varchar(50) NOT NULL DEFAULT '0',
  KEY `id` (`id`),
  KEY `entityType_season_altValue` (`entityType`,`season`,`altValue`)
)

国家/地区:

CREATE TABLE IF NOT EXISTS `countries` (
  `name` varchar(50) NOT NULL,
  `iso2` varchar(2) NOT NULL,
  `iso3` varchar(3) NOT NULL,
  `color` varchar(7) NOT NULL,
  KEY `iso3` (`iso3`)
)

游戏:

CREATE TABLE IF NOT EXISTS `games` (
  `id` int(7) NOT NULL AUTO_INCREMENT,
  `competition` varchar(10) NOT NULL,
  `season` varchar(4) NOT NULL,
  `stage` varchar(10) DEFAULT NULL,
  `gamedate` date DEFAULT NULL,
  `team1` varchar(50) NOT NULL,
  `team2` varchar(50) NOT NULL,
  `score1` tinyint(2) DEFAULT NULL,
  `score2` tinyint(2) DEFAULT NULL,
  `attendance` int(11) DEFAULT NULL,
  `location` varchar(100) DEFAULT NULL,
  `source` varchar(400) DEFAULT NULL,
  `altsource` varchar(400) DEFAULT NULL,
  `note` varchar(400) DEFAULT NULL,
  KEY `id` (`id`),
  KEY `competition_season` (`competition`,`season`),
  KEY `team_comp_season` (`team1`,`competition`,`season`)
)

团队:

CREATE TABLE IF NOT EXISTS `teams` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `shortName` varchar(20) DEFAULT NULL,
  `longName` varchar(50) NOT NULL,
  `urlSlug` varchar(50) DEFAULT NULL,
  `country` varchar(3) NOT NULL DEFAULT 'NSP',
  `competitions` varchar(50) DEFAULT NULL,
  `latitude` float(10,6) DEFAULT '0.000000',
  `longitude` float(10,6) DEFAULT '0.000000',
  `inactive` tinyint(1) DEFAULT '0',
  KEY `id` (`id`),
  KEY `long` (`longName`),
  KEY `FK_teams_countries` (`country`),
  CONSTRAINT `teams_ibfk_1` FOREIGN KEY (`country`) REFERENCES `countries` (`iso3`)
)

1 个答案:

答案 0 :(得分:-2)

我刚想到一个有趣的主意,在等待专家意见时, 尝试使用AND切换OR运算符。

条件A或条件B

等效于

不(不(条件A)和不(条件B))

祝你好运