2010-10-04 61 views
1

於是我開始了與此查詢:的MySQL我想優化這個進一步

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) 

我可以做任何其他的優化?

+1

你真的需要'SELECT *'? – nico 2010-10-04 06:09:26

+0

@nico:+1。謝謝。 – Legend 2010-10-04 06:35:21

回答

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); 
+0

我將刪除*。一個簡單的問題:如果空間不是真的問題,那麼在所有列上添加索引是否合乎邏輯? – Legend 2010-10-04 06:19:59

+0

@傳奇:是的,在許多情況下,建議。一般而言,覆蓋索引超過常規索引的主要缺點是佔用更多空間,並且插入和更新速度稍慢(或佔用更多資源)。除非你每秒插入許多新記錄,否則這很少是一個問題,而且通常可以忽略不計。 – 2010-10-04 06:41:27

+0

謝謝。我會試試看看它是否有效。我的表有20億條記錄,但我不會再更新它們。 – Legend 2010-10-04 07:39:54