MySQL - 基本2表查询慢 - 索引在哪里?
我有一个 MySQL 5.0 查询,从网页调用,经常需要 14 秒以上,而且用户不耐烦。这相当简单,从 2 个表中选择 11 列。我有三个问题:
- 连接的位置重要吗?
- where 子句的顺序重要吗?MySQL 会优化吗?
- 和索引对我的情况有帮助吗?
sql:
select table1.id, table1.DateOpened, table1.Status, table2.Name, etc
from (table1 join table2 on((table1.CurrentName = table2.id)))
where table1.Type = 'Add' and (Status = 'Open' OR Status = 'Pending');
表/列信息:
table1 has 750,000 rows, table2 1.5M rows.
indexed: table1.id, table2.id
INT columns: id, table1.CurrentName
table1.Status = always populated with 1 of 4 values,
maybe 300 are 'Open' or 'Pending'
table1.Type = 3 possible values: 'Add', 'Change', or null
与在 WHERE 子句中添加 'table1.CurrentName = table2.id' 相比,在 FROM 中加入 JOIN 有什么优势吗?
有 3 个 WHERE 子句(带有连接)。我用各种顺序组合运行 EXPLAIN,结果似乎是相同的。
我认为向 table1.CurrentName 添加索引可能会有所帮助,但现在我认为没有。我修改了查询以删除对 table2 的引用,但它仍然运行缓慢。 (参见 3b)
似乎大部分减速可能只是读取 800K 记录并查看类型和状态值。对只有 3 或 4 个可能值的这两列进行索引是否有意义?我认为只有当存在更多唯一值时才有意义。
解释结果:
+----+-------------+--------+--------+---------------+---------+---------+-----------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+--------+---------------+---------+---------+-----------------------+--------+-------------+
| 1 | SIMPLE | table1 | ALL | CurrentName | NULL | NULL | NULL | 733190 | Using where |
| 1 | SIMPLE | table2 | eq_ref | PRIMARY | PRIMARY | 4 | db.table1.CurrentName | 1 | |
+----+-------------+--------+--------+---------------+---------+---------+-----------------------+--------+-------------+
2 rows in set (0.00 sec)
I have a MySQL 5.0 query regularly taking 14+ seconds, called from a web page, and users are impatient. It's fairly simple, selecting 11 columns from 2 tables. I have three questions:
- Does placement of join matter?
- Does order of where clause matter, or will MySQL optimize?
- Would and index help in my case?
sql:
select table1.id, table1.DateOpened, table1.Status, table2.Name, etc
from (table1 join table2 on((table1.CurrentName = table2.id)))
where table1.Type = 'Add' and (Status = 'Open' OR Status = 'Pending');
table/column info:
table1 has 750,000 rows, table2 1.5M rows.
indexed: table1.id, table2.id
INT columns: id, table1.CurrentName
table1.Status = always populated with 1 of 4 values,
maybe 300 are 'Open' or 'Pending'
table1.Type = 3 possible values: 'Add', 'Change', or null
Is there any advantage JOINing in the FROM, vs adding 'table1.CurrentName = table2.id' in the WHERE clause?
There are 3 WHERE clauses (with the join). I ran EXPLAIN with various order combinations, and results seemed to be the same.
I thought adding an index to table1.CurrentName may help, but now I'm thinking not. I modified the query to remove references to table2, and it still ran slow. (see 3b)
Seems like the bulk of the slowdown may be just reading 800K records looking at the Type and Status values. Does it make sense to index these two columns, where there are only 3 or 4 possible values? I thought it only made sense when there were more unique values.
explain results:
+----+-------------+--------+--------+---------------+---------+---------+-----------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+--------+---------------+---------+---------+-----------------------+--------+-------------+
| 1 | SIMPLE | table1 | ALL | CurrentName | NULL | NULL | NULL | 733190 | Using where |
| 1 | SIMPLE | table2 | eq_ref | PRIMARY | PRIMARY | 4 | db.table1.CurrentName | 1 | |
+----+-------------+--------+--------+---------------+---------+---------+-----------------------+--------+-------------+
2 rows in set (0.00 sec)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它们的写入顺序对于 INNER JOIN 来说并不重要。
不会。WHERE 子句中的写入顺序对于 MySQL 查询解析器和优化器来说并不重要
有潜力。 table1 上的复合索引 type_status (Type, Status) 可能会有所帮助,因为这是 WHERE 子句可以减少初始行读取的地方。
对于 INNER JOIN,JOIN 条件是否位于 FROM 子句或 WHERE 子句中并不重要。
table1.CurrentName 上的索引对查询没有帮助。
这强化了我上面的想法。要添加复合索引(在线可能不是一件好事),就像
选择性肯定有帮助,但高基数并不是唯一合适的环境。
The order they are written does not matter for INNER JOINs.
No. The written order in a WHERE clause does not matter to the MySQL query parser and optimizer
Potentially. A compound index type_status (Type, Status) on table1 could help since that is where your WHERE clause could reduce the initial rows read.
For INNER JOINs, it doesn't matter if the JOIN condition is in the FROM clause or the WHERE clause.
An index on table1.CurrentName would not help the query.
This reinforces my thought above. To add the compound index (potentially not a good thing to do online), it'd be something like
Selectivity definitely helps, but high cardinality is not the only suitable context.