nai*_*sts 6 mysql indexing performance join
一位同事让我解释索引(指数?)如何提升绩效; 我试图这样做,但我自己也搞糊涂了.
我使用下面的模型进行说明(错误/诊断日志记录数据库).它由三个表组成:
System和TraceTypes表的外键我使用MySQL进行演示,但我不记得我使用过的表格类型.我认为这是InnoDB.
System TraceTypes
----------------------------- ------------------------------------------
| ID | Name | | ID | Code | Description |
----------------------------- ------------------------------------------
| 1 | billing | | 1 | Info | Informational mesage |
| 2 | hr | | 2 | Warning| Warning only |
----------------------------- | 3 | Error | Failure |
| ------------------------------------------
| ------------|
Traces | |
--------------------------------------------------
| ID | System_ID | TraceTypes_ID | Message |
--------------------------------------------------
| 1 | 1 | 1 | Job starting |
| 2 | 1 | 3 | System.nullr..|
--------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
首先,我在所有表中添加了一些记录,并证明下面的查询在0.005秒内执行:
select count(*) from Traces
inner join System on Traces.System_ID = System.ID
inner join TraceTypes on Traces.TraceTypes_ID = TraceTypes.ID
where
System.Name='billing' and TraceTypes.Code = 'Info'
Run Code Online (Sandbox Code Playgroud)
然后我生成了更多的数据(还没有索引)
现在上一个查询花了8-10秒.
我在Traces.System_ID列和Traces.TraceTypes_ID列上创建了索引.现在这个查询以毫秒为单位执行:
select count(*) from Traces where System_id=1 and TraceTypes_ID=1;
Run Code Online (Sandbox Code Playgroud)
这也很快:
select count(*) from Traces
inner join System on Traces.System_ID = System.ID
where System.Name='billing' and TraceTypes_ID=1;
Run Code Online (Sandbox Code Playgroud)
但加入所有三个表的上一个查询仍需要8-10秒才能完成.
只有当我创建了一个复合索引(索引中包含System_ID和TraceTypes_ID列)时,速度才会降低到毫秒.
我之前教过的基本陈述是"用于加入的所有列都必须编入索引".
然而,在我的情况我有两个索引System_ID和TraceTypes_ID,但是MySQL并没有使用它们.问题是 - 为什么?我的投注是 - 项目计数比率100:10,000,000:50使得单列索引太大而无法使用.但这是真的吗?
首先,分析慢速 SQL 语句的正确且最简单的方法是执行 EXPLAIN。了解优化器如何选择其计划,并思考原因以及如何改进。我建议研究仅使用 2 个单独索引的 EXPLAIN 结果,以了解 mysql 如何执行您的语句。
我对 MySQL 不是很熟悉,但 MySQL 4 似乎有一个限制,即查询中涉及的每个表只能使用一个索引。自 MySQL 5(索引合并)以来似乎对此有所改进,但我不确定它是否适用于您的情况。再次强调,EXPLAIN 应该告诉你真相。
即使允许每个表使用 2 个索引(MySQL 5),使用 2 个单独的索引通常也比复合索引慢。与使用复合索引的单遍相比,使用 2 个单独的索引需要索引合并步骤。
多列索引与索引合并可能会有所帮助,它使用 MySQL 5.4.2。