2014-03-07 44 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