我有一个超过200万行的表,我需要在循环中快速选择查询。
SELECT ID,WebSite FROM `CompanyData` WHERE A1='data1' OR A2='data2' OR A3='data3'
它需要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 |
+----+-------------+----------+-------+---------------+------+---------+------+---------+-------------------------------------------+
这是表结构:
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
最近我已经在表格中插入了另外1000万条记录。然后一样 查询大约需要3秒钟。
请建议一种改进Select查询查询的方法。即使我准备重组桌子。
由于
答案 0 :(得分:3)
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';
请注意,这会使用UNION
而不是UNION ALL
。 UNION ALL
的替代版本看起来像这样(假设值永远不是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';
对于此查询,最佳索引是复合索引:(A1, ID, WebSite)
,(A2, A1, ID, Website)
和(A3, A1, A2, ID, WebSite)
。
答案 1 :(得分:0)
跨列显示的数组是有问题的。
试一试......
CREATE TABLE `CompanyData` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`WebSite` varchar(150) DEFAULT NULL,
`CompanyName` varchar(200) DEFAULT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `WebSite` (`WebSite`,`CompanyName`),
KEY `CompanyName` (`CompanyName`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `Stuff` (
`CompanyID` int(11) NOT NULL
`A` varchar(150) NOT NULL,
PRIMARY KEY (A, CompanyID)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SELECT c.ID, c.WebSite
FROM CompanyData AS c
JOIN Stuff AS s ON c.ID = s.CompanyID
WHERE s.A IN ('data1', 'data2', 'data3');