2014-03-07 100 views
2

我有一個50列的表。我定義一個指數(不是唯一的)具有以下6列:MySQL:爲什麼沒有使用索引的所有鍵?

rdsr_id (int), 
StartOfXrayIrradiation (datetime), 
PatientsBirthDate (date), 
DeviceObserverUID (varchar(100)), 
IdentifiedProtocolShort (varchar(50)), 
RedundantEntryFromDoseSummary (tinyint(1)) 

的表稱爲報告,有大約20'000行和增長。運行以下查詢時,結果顯示僅使用索引的4個鍵。

EXPLAIN EXTENDED SELECT r.PatientID, r.StartOfXrayIrradiation, MeanCTDIvol_in_mGy 
FROM report r 
INNER JOIN ct_irradiation_events e ON r.rdsr_id = e.rdsr_id 
INNER JOIN patient_age_categories a ON (DATEDIFF(r.StartOfXrayIrradiation, r.PatientsBirthDate) <= a.max_age_days 
    AND DATEDIFF(r.StartOfXrayIrradiation, r.PatientsBirthDate) >= a.min_age_days 
    AND a.description = 'Erwachsene') 
WHERE MeanCTDIvol_in_mGy IS NOT NULL 
AND r.DeviceObserverUID = '2.25' 
AND r.IdentifiedProtocolShort = 'XXXXX' 
AND r.RedundantEntryFromDoseSummary =0 
AND e.CTAcquisitionType != 'Constant Angle Acquisition' 
AND DATEDIFF(r.StartOfXrayIrradiation, '2013-01-06') >=0 
AND DATEDIFF(r.StartOfXrayIrradiation, '2014-03-06') <=0; 

結果爲表報告:

> id: 1 
> select_type: SIMPLE 
> table: r 
> type: ref 
> possible_keys: TimelineHistogramQueries 
> key: TimelineHistogramQueries 
> key_len: 4 
> ref: rdsr.e.rdsr_id 
> rows: 1 
> filtered: 100.00 
> Extra: Using where 

,所以我猜列IdentifiedProtocolShort和RedundantEntryFromDoseSummary不習慣?查詢的結果是1400行。從WHERE子句中刪除兩列時,找到9500行。順便說一句:我創建索引後,運行「ANALYZE TABLE報告」,如果這很重要...

爲什麼不是索引的所有鍵使用?我應該改變我的索引嗎?

回答

2

假設你TimelineHistogramQueries關鍵是在你的順序列出六列複合鍵,那麼4(字節)key_len值確實表明,只有rdsr_id列被索引使用:這由refrdsr.e.rdsr_id支持。

你問爲什麼IdentifiedProtocolShortRedundantEntryFromDoseSummary(索引中的第5列和第6列)沒有被使用。如Multiple-Column Indexes所述:

如果列沒有形成索引的最左邊前綴,那麼MySQL不能使用該索引執行查找。

如果您不需要該索引的列按其當前順序進行任何其他查詢,則只需重新排列列;否則,您可能需要定義第二個索引。

+0

我沒有正確理解EXPLAIN的輸出。所以key_len 4表示4個字節而不是4個鍵。我以前閱讀過文檔。索引的第二個鍵是StartOfXrayIrradiation,這是查詢中使用的表格報告的第二列。從索引的左側開始,接下來是rdsr_id StartOfXrayIrradiation。那爲什麼不使用呢?其實我試圖爲這個查詢做一個索引。如您所見,在查詢中多次使用StartOfXrayIrradiation。我還需要多次將它添加到索引中嗎?謝謝! – nightlyop

+0

@nightlyop:要清楚,你有一個索引,每列有六列或六個索引嗎? – eggyal

+0

一個6列的索引。 – nightlyop

0

取決於您想要查詢的內容。如果您有興趣瞭解哪些日期,請留下您的第一個查詢中的患者ID和DOB。你的病人有X光片等,除非你按年齡進行分析。通過嘗試將所有索引編制在系統上會讓你感到困惑。

+0

首先,您得到所有​​您需要的變量。索引將您的價值整齊排列。如果您需要查看年齡組,則您的查詢將涉及DOB。如果我們說,你的下一個重要變量是X射線的日期,那麼將其添加到索引。患者ID將在您的查詢中,但其對索引的重要性是次要的。那並不重要。 –

+0

對不起,我沒有明白。 PatientID不在索引中... – nightlyop