【问题标题】:MySQL I want to optimize this furtherMySQL 我想进一步优化这个
【发布时间】:2010-10-04 06:01:48
【问题描述】:

所以我从这个查询开始:

SELECT * FROM TABLE1 WHERE hash IN (SELECT id FROM temptable);

花了很长时间,所以我解释了:

mysql> explain SELECT * FROM TABLE1 WHERE hash IN (SELECT id FROM temptable);
+----+--------------------+-----------------+------+---------------+------+---------+------+------------+-------------+
| id | select_type        | table           | type | possible_keys | key  | key_len | ref  | rows       | Extra       |
+----+--------------------+-----------------+------+---------------+------+---------+------+------------+-------------+
|  1 | PRIMARY            | TABLE1          | ALL  | NULL          | NULL | NULL    | NULL | 2554388553 | Using where | 
|  2 | DEPENDENT SUBQUERY | temptable       | ALL  | NULL          | NULL | NULL    | NULL |       1506 | Using where | 
+----+--------------------+-----------------+------+---------------+------+---------+------+------------+-------------+
2 rows in set (0.01 sec)

它没有使用索引。所以,我的第二遍:

mysql> explain SELECT * FROM TABLE1 JOIN temptable ON TABLE1.hash=temptable.hash;
+----+-------------+-----------------+------+---------------+----------+---------+------------------------+------+-------------+
| id | select_type | table           | type | possible_keys | key      | key_len | ref                    | rows | Extra       |
+----+-------------+-----------------+------+---------------+----------+---------+------------------------+------+-------------+
|  1 | SIMPLE      | temptable       | ALL  | hash          | NULL     | NULL    | NULL                   | 1506 |             | 
|  1 | SIMPLE      | TABLE1          | ref  | hash          | hash     | 5       | testdb.temptable.hash  |  527 | Using where | 
+----+-------------+-----------------+------+---------------+----------+---------+------------------------+------+-------------+
2 rows in set (0.00 sec)

我可以做任何其他优化吗?

【问题讨论】:

  • 你真的需要SELECT *吗?

标签: database mysql query-optimization


【解决方案1】:

您可以通过使用covering index 获得更快的速度,但会消耗额外的空间。覆盖索引是一种可以满足查询中所有请求的列而无需进一步查找聚集索引的索引。

首先摆脱SELECT * 并明确选择您需要的字段。然后,您可以将 SELECT 子句中的所有字段添加到复合索引的右侧。例如,如果您的查询如下所示:

SELECT  first_name, last_name, age 
FROM    table1 
JOIN    temptable ON table1.hash = temptable.hash;

然后你可以有一个看起来像这样的覆盖索引:

CREATE INDEX ix_index ON table1 (hash, first_name, last_name, age);

【讨论】:

  • 我将删除 *.一个快速的问题:如果空间不是真正的问题,那么在所有列上添加索引是否合乎逻辑?
  • @Legend:是的,在很多情况下都是推荐的。一般来说,覆盖索引相对于常规索引的主要缺点是它占用更多空间,并且插入和更新变得有点慢(或占用更多资源)。除非您每秒插入许多新记录,否则这很少会成为问题,而且通常可以忽略不计。
  • 谢谢。我会尝试一下,看看它是否有效。我的表有 20 亿条记录,但我不会再更新它们了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-08
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
  • 1970-01-01
相关资源
最近更新 更多