MYSQL - 具有多个 OR 条件的选择查询很慢

San*_*osh 2 mysql optimization select

我有一个超过 200 万行的表,我需要在循环中快速对其进行选择查询。

SELECT ID,WebSite FROM `CompanyData` WHERE A1='data1' OR A2='data2' OR A3='data3'
Run Code Online (Sandbox Code Playgroud)

它需要 300 毫秒。我觉得不应该花这么多时间。这是该查询的 EXPLAIN:

--------+---------------------------------------------------------------------------------------------------------------------------+
| id | select_type | table    | type  | possible_keys  | key      |  key_len    | ref  | rows  | Extra                              |
+----+-------------+----------+-------+---------------+------+---------+------+---------+-------------------------------------------+
|  1 | SIMPLE     | CompanyData | index | A1,A2,A3     | A1,A2,A3 | 153,153,153 | NULL | 3     | Using union(A1,A2,A3); Using where |
+----+-------------+----------+-------+---------------+------+---------+------+---------+-------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

这是表结构:

CREATE TABLE `CompanyData` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `WebSite` varchar(150) DEFAULT NULL,
  `CompanyName` varchar(200) DEFAULT NULL,
  `A1` varchar(150) DEFAULT NULL,
  `A2` varchar(150) DEFAULT NULL,
  `A3` varchar(150) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `WebSite` (`WebSite`,`CompanyName`),
  KEY `CompanyName` (`CompanyName`),
  KEY `A1` (`A1`),
  KEY `A2` (`A2`),
  KEY `A3` (`A3`)
) ENGINE=InnoDB AUTO_INCREMENT=3931223 DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)

最近我又在表中插入了 1000 万条记录。然后相同的查询大约需要 3 秒。

请提出一种改进选择查询查找的方法。甚至我都准备好重组表格。

谢谢

Gor*_*off 5

MySQL 很难用OR. 你可能会更好地尝试:

SELECT ID, WebSite
FROM `CompanyData`
WHERE A1 = 'data1'
UNION
SELECT ID, WebSite
FROM `CompanyData`
WHERE A2 = 'data2' 
UNION
SELECT ID, WebSite
FROM `CompanyData`
WHERE A3 = 'data3';
Run Code Online (Sandbox Code Playgroud)

请注意,这使用UNION代替UNION ALL。一个UNION ALL看起来像这样的替代版本(假设值是 never NULL):

SELECT ID, WebSite
FROM `CompanyData`
WHERE A1 = 'data1'
UNION ALL
SELECT ID, WebSite
FROM `CompanyData`
WHERE A2 = 'data2' AND A1 <> 'data1'
UNION ALL
SELECT ID, WebSite
FROM `CompanyData`
WHERE A3 = 'data3' AND A1 <> 'data1' AND A2 <> 'data2';
Run Code Online (Sandbox Code Playgroud)

对于此查询,最好的指标是综合指数: (A1, ID, WebSite)(A2, A1, ID, Website),和(A3, A1, A2, ID, WebSite)