该表目前是一个400万(~50 GB)的行表并且正在快速增长。
我们不希望包含EndTime无效且因此少于StartTime的任何行,因为它至少有1,000行,它们为零。
我的问题是什么样的索引最适合这三个查询? 我猜可能是一个首先是EndTime和StartTime第二的复合索引?
StartTime和EndTime字段都包含unix时间戳,如:1401951888
SELECT AVG(EndTime-StartTime) FROM sessions WHERE EndTime>StartTime;
SELECT MAX(EndTime-StartTime) FROM sessions WHERE EndTime>StartTime;
SELECT MIN(EndTime-StartTime) FROM sessions WHERE EndTime>StartTime;
+----------------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+------------+------+-----+---------+-------+
| Uuid | char(36) | NO | PRI | NULL | |
| StartTime | int(11) | YES | | NULL | |
| EndTime | int(11) | YES | | NULL | |
+----------------------+------------+------+-----+---------+-------+
答案 0 :(得分:4)
该表目前是一个400万(~50 GB)的行表并且正在快速增长。
只有3列的4M行,它的50GB?哇......某处有问题吗?
我们不希望包含EndTime无效且因此少于StartTime的任何行,因为它至少有1,000行,而且它们为零。
由于没有其他条件,查询将必须处理整个表,减去1000行。因此,任何指数都将毫无用处。
除非表中的列数多于您显示的列数,否则索引的唯一用途将比磁盘表小得多,因此扫描速度要快得多。
现在,在MySQL的最新版本中,您现在可以在虚拟列上创建functional indexes!因此,您可以在:
上创建索引endTime - startTime
如果你的max()和min()使用索引,它们将是瞬时的,因为在有序集合中找到min / max是一个O(1)操作,只需要查看第一个或最后一个条目。但是,您的avg()当然必须检查所有行以计算平均值。