我有一个包含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报告”,如果这很重要......
为什么不使用索引的所有键?我应该改变我的索引吗?
答案 0 :(得分:2)
假设您的TimelineHistogramQueries
键是按顺序列出的六列的复合键,那么key_len
值4(字节)确实表示只有rdsr_id
列在索引中使用:ref
的值rdsr.e.rdsr_id
支持此列。
您问为什么IdentifiedProtocolShort
和RedundantEntryFromDoseSummary
(索引中的第5列和第6列)未被使用。正如Multiple-Column Indexes所述:
如果列不构成索引的最左前缀,则MySQL无法使用索引执行查找。
如果您不要求此索引的列按其当前顺序进行任何其他查询,则只能对列重新排序;否则,您可能需要定义第二个索引。
答案 1 :(得分:0)
取决于您的查询内容。如果您有兴趣查看在哪个日期,请从第一个查询中留出患者ID和DOB,例如您的患者进行了X光检查等。除非您按年龄进行分析。您通过尝试将其全部编入索引来混淆系统。