这是我的表:
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中遇到某种瓶颈百万,并想了解其他可能提高绩效的策略。
答案 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
更快。
(留给读者的剩余细节。)
<强>类比强>
假设一个人有多个电话号码(座机,小区,工作等),我想根据一个电话号码查找他的记录。因此,我构建了一个phone
:personID
对的表,并在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
。