MySQL:为什么不使用索引的所有键?

时间:2014-03-07 10:34:38

标签: mysql

我有一个包含50列的表格。我用以下6列定义了一个索引(不唯一):

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

该表名为report,大约有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 个答案:

答案 0 :(得分:2)

假设您的TimelineHistogramQueries键是按顺序列出的六列的复合键,那么key_len值4(字节)确实表示只有rdsr_id列在索引中使用:ref的值rdsr.e.rdsr_id支持此列。

您问为什么IdentifiedProtocolShortRedundantEntryFromDoseSummary(索引中的第5列和第6列)未被使用。正如Multiple-Column Indexes所述:

  

如果列不构成索引的最左前缀,则MySQL无法使用索引执行查找。

如果您不要求此索引的列按其当前顺序进行任何其他查询,则只能对列重新排序;否则,您可能需要定义第二个索引。

答案 1 :(得分:0)

取决于您的查询内容。如果您有兴趣查看在哪个日期,请从第一个查询中留出患者ID和DOB,例如您的患者进行了X光检查等。除非您按年龄进行分析。您通过尝试将其全部编入索引来混淆系统。