2011-08-09 224 views
3

我在我的數據庫中運行以下查詢:MySQL查詢很慢

SELECT e.id_dernier_fichier 
FROM Enfants e JOIN FichiersEnfants f 
ON e.id_dernier_fichier = f.id_fichier_enfant 

和查詢運行正常。如果我修改這樣的查詢:

SELECT e.codega 
FROM Enfants e JOIN FichiersEnfants f 
ON e.id_dernier_fichier = f.id_fichier_enfant 

查詢變得非常慢!問題是我想在表e和f中選擇許多列,查詢最多需要1分鐘!我嘗試了不同的修改,但沒有任何效果我在e.codega上也有id_ *上的索引。嬰兒有9000條生產線,FichiersEnfants有20000條生產線。有什麼建議麼 ?

這裏是要求信息(抱歉,沒有從一開始就顯示它們):

Table FichiersEnfants Table Enfants Index Enfants Explain Query 1 Explain Query 2

+0

這些表中的任何一個實際上是一個視圖,你可以在這裏張貼查詢與EXPLAIN結果。 –

+0

表格架構?索引定義?表中的記錄數量? MySQL版本(有點幫助)?硬件規格? – ajreal

+0

e.codega和e.id_dernier_fichier的數據類型是什麼? – jadarnel27

回答

2

在性能上的差異是可能由於e.id_dernier_fichier在被用於JOIN的索引,但e.codega不在索引。

如果沒有這兩個表及其所有索引的完整定義,則無法確定。另外,爲兩個查詢包含兩個EXPLAIN PLAN將會有所幫助。


但就目前而言,我如果聚簇索引詳細說明幾件事情......

(這也適用於主鍵),數據實際物理存儲在INDEX的順序。這意味着,知道你要在INDEX 位置x也含蓄表示要在表位置x

但是,如果INDEX未被聚集,INDEX只是爲您提供查找。有效地說位置x在INDEX對應於位置y在表中。

這裏的重要性是訪問未在INDEX中指定的字段。這樣做意味着您必須切實轉到TABLE以獲取數據。在一個CLUSTERED INDEX的情況下,你已經在那裏了,找到這個字段的開銷很小。如果指數不聚集,但是,你effectifvely必須將表連接到索引,然後找到你感興趣的領域


注意。在(id_dernier_fichier, codega)上有一個複合指數,它與僅在(id_dernier_fichier)上的一個指數和在(codega)上的單獨指數有很大不同。


在您的查詢的情況下,我不認爲你需要做任何改動的代碼。但你可能受益於改變指標。

你提到你想訪問很多字段。將所有這些字段放在一個複合索引中可能不是最好的解決方案。相反,您可能需要在(id_dernier_fichier)上創建一個CLUSTERED INDEX。這意味着一旦找到了* id_dernier_fichier *,您就已經在正確的位置獲得所有其他字段。


編輯Note About MySQL and CLUSTERED INDEXes

13.2.10.1。羣集和輔助索引

每個InnoDB表有一個特殊的索引稱爲其中的行中的數據被存儲在聚簇索引:

  • 如果你定義你的表的主鍵,InnoDB使用它作爲聚集指數。
  • 如果您沒有爲您的表定義PRIMARY KEY,MySQL會選擇第一個只有NOT NULL列作爲主鍵的UNIQUE索引,而InnoDB將它用作聚簇索引。
  • 如果表沒有PRIMARY KEY或合適的UNIQUE索引,InnoDB會在包含行ID值的合成列內部生成隱藏聚簇索引。這些行按照InnoDB分配給此表中的行的ID進行排序。行ID是一個6字節的字段,隨着新行的插入而單調遞增。因此,由行ID排序的行在物理上處於插入順序。
+0

OP提到這兩個字段都被編入索引。 – jadarnel27

+0

對不起,我現在在我的問題中添加了所有信息。感謝您的幫助! – Emanuel

+0

@ jadarnel27:這是真的,但沒有提及它們是否是單獨的索引,複合索引,並且缺少EXPLAIN PLAN沒有提及哪些索引正在用於這些查詢。所有這些信息對於理解查詢的性能特徵都是至關重要的。 – MatBailie