2015-06-30 174 views
0

更新:Mysql優化:有什麼辦法可以讓這個更快?

感謝所有的幫助。我將總結答案。

從@Jaydee,他的回答成功地將結果減少到0.09秒,並且與LIMIT中的數字成線性關係。

SELECT * FROM(選擇table1.id從表1其中 table1.id < 100000爲了通過table1.id DESC LIMIT 1000 table1_id)點t1內連接上t1.table2_id = table2.id table2的左加入表3 on t1.table3_id = table3.id order by t1.id;

從@Rick詹姆斯,他提到,這可能是表2的問題,因爲我的表2只有幾列,我可以離開它,並做加盟自己,即使在客戶端!

所以我刪除表2,它只有0.02s!

選擇table1id作爲table1_idtable1左加入table3table1table3_id = table3id其中table1id order by table1id desc limit 1000;

最後我發現如果我把table2從inner join改成left join,那麼所有的痛苦都消失了,這是0.03s!

選擇table1id作爲table1_id來自table1左加入table2table1table2_id = table2id左加入table3table1table3_id = table3id其中table1id < order by table1id desc limit 1000;

再次感謝您的幫助!

==============================

注:我RAM有限的嵌入式服務器上運行(約1G,足以放入所有數據,20萬數據),並使用SD卡作爲存儲。

select table1.id from table1 where id < 100000 order by id desc limit 1000;

(0.01秒)

選擇table1id作爲table1_id來自table1內部加入table2table1上。 table2_id = table2id其中table1id < order by table1id desc limit 1000;

(0.40s)

選擇table1id作爲table1_id來自table1內部加入table2table1上。 table2_id = table2id其中table1id < order by table1id desc limit 1000;

(0.01秒)

選擇table1id作爲table1_id來自table1內部加入table2table1上。 table2_id = table2id左加入table3table1table3_id = table3id其中table1id < order by table1id desc limit 1000;

(2.31s)

選擇table1id作爲table1_id來自table1內部加入table2table1上。 table2_id = table2id左加入table3table1table3_id = table3id其中table1id < order by table1id desc limit 1000;

(0.03秒)


正如評論所說,我用瞭解釋,但我真的不明白這是什麼解釋說。請幫我檢查一下。以下是最長的2.31s。

+----+-------------+----------------------+--------+-------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------------+-------+----------------------------------------------+ 
| id | select_type | table    | type | possible_keys              | key         | key_len | ref           | rows | Extra          | 
+----+-------------+----------------------+--------+-------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------------+-------+----------------------------------------------+ 
| 1 | SIMPLE  | table2    | index | PRIMARY,table2_id_index           | table1_id_index      | 4  | NULL          |  1 | Using index; Using temporary; Using filesort | 
| 1 | SIMPLE  | table1    | ref | PRIMARY,table1_table2_id_foreign,table1_id_index     | table1_table2_id_foreign    | 4  | videocap.table2.id       | 27222 | Using where         | 
| 1 | SIMPLE  | table3    | eq_ref | PRIMARY               | PRIMARY        | 4  | videocap.table1.table3_id     |  1 | Using index         | 
+----+-------------+----------------------+--------+-------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------------+-------+----------------------------------------------+ 

從降序表結果

表1:

+-------------------------+------------------+------+-----+---------------------+----------------+ 
| Field     | Type    | Null | Key | Default    | Extra   | 
+-------------------------+------------------+------+-----+---------------------+----------------+ 
| id      | int(10) unsigned | NO | PRI | NULL    | auto_increment | 
| table2_id  | int(10) unsigned | NO | MUL | NULL    |    | 
| table3_id | int(10) unsigned | NO | MUL | 0     |    | 
| created_at    | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
| updated_at    | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
+-------------------------+------------------+------+-----+---------------------+----------------+ 

表2:

+-----------------+------------------+------+-----+---------------------+----------------+ 
| Field   | Type    | Null | Key | Default    | Extra   | 
+-----------------+------------------+------+-----+---------------------+----------------+ 
| id    | int(10) unsigned | NO | PRI | NULL    | auto_increment | 
| created_at  | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
| updated_at  | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
+-----------------+------------------+------+-----+---------------------+----------------+ 

表3:

+---------------------------+------------------+------+-----+---------------------+----------------+ 
| Field      | Type    | Null | Key | Default    | Extra   | 
+---------------------------+------------------+------+-----+---------------------+----------------+ 
| id      | int(10) unsigned | NO | PRI | NULL    | auto_increment | 
| created_at    | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
| updated_at    | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
+---------------------------+------------------+------+-----+---------------------+----------------+ 
+0

對所有慢速查詢的'explain select'說明是什麼?加入密鑰索引? –

+0

你有'table1.id'上的索引嗎? – Jaydee

+0

table1.id,table2.id,table3.id是主鍵。 table1.table2_id,table1.table3_id是普通索引(來自desc table1的mul)。 – user534498

回答

1

看起來像table2有1行。那是對的嗎?每個表中有多少行?

在table2中只有一行,優化器似乎決定讓它開始。

在所有情況下,PRIMARY KEY(id),特別是如果你正使用InnoDB,是最佳的

where  table1.id < $number 
    order by table1.id desc 

然而,如果大多數表都有編號< 100000,則優化可能會(錯誤地)決定做一個表掃描(因爲它沒有考慮到LIMIT)。你使用什麼版本? 5.6在這方面有一些改進。

請記住,查詢有數百萬個變體。雖然我很欣賞你試圖隔離查詢的重要部分;您可能會發現將任何回答應用到「真實」查詢中可能會遇到其他一些呃逆。

+0

謝謝。表1目前只有1行,但後面會有更多(不會太多),否則表2沒有意義。考慮到您的線索,我將表2推向外部,它要快得多。謝謝。 – user534498

2

這是如何執行的? (Ooops。Corrected)

select * 
    from 
     (SELECT table1.id as table1_id 
      from table1 
      where table1.id < 100000 
      order by table1.id desc 
      limit 1000 
    ) t1 
    inner join table2 on t1.table2_id = table2.id 
    left join table3 on t1.table3_id = table3.id 
    order by t1.id; 
+0

是的,這會減少到0.09s,並且與LIMIT是線性的。如果我將LIMIT減少到100,現在將是0.01秒。謝謝。 – user534498

+0

是的,子選擇最小化了加入的行數。 – Jaydee

相關問題