OR运算符中的MySQL性能

时间:2016-11-01 10:24:30

标签: mysql indexing innodb

这是我的表:

CREATE TABLE `e_relationship` (
`OID` int(11) NOT NULL AUTO_INCREMENT,
`E_E_OID` int(11) NOT NULL,
`E_E_OID2` int(11) NOT NULL,
`REL_DISPLAY` text NOT NULL,
`APP_OID` int(11) NOT NULL,
`META_OID` int(11) NOT NULL,
`STORE_DATE` datetime NOT NULL,
`UID` int(11) DEFAULT NULL,
PRIMARY KEY (`OID`),
KEY `Left_Entity` (`E_E_OID`),
KEY `Right_Entity` (`E_E_OID2`),
KEY `Meta_Left` (`META_OID`,`E_E_OID`),
KEY `Meta_Right` (`META_OID`,`E_E_OID2`)
) ENGINE=InnoDB AUTO_INCREMENT=310169 DEFAULT CHARSET=utf8;

以下查询大约需要2.5-3ms,结果集为1,290行,表中的总行数为1,008,700:

SELECT * FROM e_relationship WHERE e_e_oid=@value1 OR e_e_oid2=@value1

这是EXPLAIN

的结果
id: 1
select_type: SIMPLE
table: e_relationship
type: index_merge
possible_keys: Left_Entity,Right_Entity
key: Left_Entity,Right_Entity
key_len: 4,4
ref: NULL
rows: 1290
Extra: Using union(Left_Entity,Right_Entity); Using where

我想加快这个问题,因为这在我的系统中非常关键,我不确定我是否因为记录的数量已经通过一个而在mysql中遇到某种瓶颈百万,并想了解其他可能提高绩效的策略。

2 个答案:

答案 0 :(得分:1)

有时MySQL在优化UNION查询时遇到问题。在这种情况下,您可以使用SELECT * FROM relationship WHERE e_e_oid = @value1 UNION SELECT * FROM relationship WHERE e_e_oid2 = @value2 将其拆分为两个查询:

Using union

每个子查询都将使用适当的索引,然后合并结果。

但是,在简单的情况下,MySQL可以自动执行此转换,并且它在您的查询中执行此操作。这就是EXPLAIN输出中{{1}}的含义。

答案 1 :(得分:0)

有一张E_E_OIDs的表格。每e_relationship个(最多)2行。然后

SELECT ...
    FROM eeoids AS ee
    JOIN e_relationship AS er ON er.ooid = ee.oid

从2列更改为1列。并摆脱2个索引。

OR的效果是否比UNION更快。

(留给读者的剩余细节。)

<强>类比

假设一个人有多个电话号码(座机,小区,工作等),我想根据一个电话号码查找他的记录。因此,我构建了一个phonepersonID对的表,并在phone上对其进行索引。然后我做

SELECT ...
    FROM Phones AS nums
    JOIN Persons AS x ON x.personID = nums.personID
    WHERE nums.phone = '123-555-1212'

注意:Persons表中没有电话号码。

您的E_E_OID就像我的phone