我有一些表:MySQL的排序上加入表列極其緩慢(臨時表)
object
person
project
[...] (some more tables)
type
對象表有外鍵的所有其他表。
現在我喜歡的查詢:
SELECT * FROM object
LEFT JOIN person ON (object.person_id = person.id)
LEFT JOIN project ON (object.project_id = project.id)
LEFT JOIN [...] (all other joins)
LEFT JOIN type ON (object.type_id = type.id)
WHERE object.customer_id = XXX
ORDER BY object.type_id ASC
LIMIT 25
這工作得很好,速度快,即使是大的結果集。例如,我有90000個對象,查詢大約需要3秒。結果非常大,因爲這些表有很多列,並且所有列都被提取。有關信息:我將Sympel與Propel,InnoDB和「doSelectJoinAll」功能結合使用。
但如果做一個查詢像(由type.name排序):
SELECT * FROM object
LEFT JOIN person ON (object.person_id = person.id)
LEFT JOIN project ON (object.project_id = project.id)
LEFT JOIN [...] (all other joins)
LEFT JOIN type ON (object.type_id = type.id)
WHERE object.customer_id = XXX
ORDER BY type.name ASC
LIMIT 25
的查詢需要約200秒!
說明:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | object | ref | object_FI_2 | object_FI_2 | 4 | const | 164966 | Using where; Using temporary; Using filesort
1 | SIMPLE | person | eq_ref | PRIMARY | PRIMARY | 4 | db.object.person_id | 1
1 | SIMPLE | ... | eq_ref | PRIMARY | PRIMARY | 4 | db.object...._id | 1
1 | SIMPLE | type | eq_ref | PRIMARY | PRIMARY | 4 | db.object.type_id | 1
我在PROCESSLIST看到,MySQL正在對連接表這樣的排序創建臨時表。
將索引添加到type.name中並沒有提高性能。只有大約800個類型的行。
我發現很多的連接和大的結果是問題,因爲如果我做一個查詢只有一個連接,如:
SELECT * FROM object
LEFT JOIN type ON (object.type_id = type.id)
WHERE object.customer_id = XXX
ORDER BY type.name ASC
LIMIT 25
它的工作原理預期的快。
有沒有一種方法來改善這樣的排序查詢上有很多連接表的大結果集?或者,在連接的表格列上排序是一種壞習慣,而這不應該完成?
謝謝
用EXPLAIN結果編輯你的問題 – Mihai
好吧,我爲有問題的查詢添加了解釋結果 – CrashOverwrite