【发布时间】:2017-03-14 11:31:10
【问题描述】:
这是我的桌子:
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,结果集为1290行,表中总行数为1008700:
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.5-3 毫秒似乎是合理的。
-
你可以试试IN算子。
-
首先(正如 Mihai 所说),对于 1M 记录表来说,3ms 是相当不错的响应时间。其次,尝试监控系统(CPU、内存、磁盘),看看是否有任何达到高百分比。
-
根据解释,MySQL 已经为您的查询使用了索引合并优化,这是您在不使用显式联合的情况下获得的最快速度。您在对已删除答案的评论中说工会速度较慢。这是作为开发人员所能得到的。从此时起,将任务交给 DBA,后者可以微调 MySQL 设置以提高查询性能。不过,我倾向于同意 2-3ms 似乎是相当快的性能的观点。
-
您的查询已按原样优化,3ms 是一个不错的结果。如果您不需要所有列并添加覆盖索引,则可以保存表查找(要对其进行测试,请尝试
select id from而不是select * from),否则,这取决于外部因素:您如何调用查询(例如在 php 中使用准备好的语句),运行多少/什么其他查询,以及您的整体数据库性能(主要是:服务器价格)。估计:对于 1M 行(如果text列不太大),您的查询直接在 MySQL 中在具有足够内存的空闲(中途)cpu 上运行,应该只显示 0.000 秒。