适当的InnoDB表索引

时间:2016-07-07 07:15:42

标签: mysql indexing sql-optimization

我有一个包含以下列的InnoDB表

  • id MEDIUMINT UNSIGNED AUTO_INCREMENT
  • a VARBINARY(16)
  • b CHAR(2)
  • c VARCHAR(100)
  • d MEDIUMINT UNSIGNED
  • e TINYINT UNSIGNED,范围0-49

我将在大多数时间执行此类查询

public static void main(String[] args)

我应该如何设置

的索引
  1. 最大SELECT速度
  2. 体面的SELECT速度和高INSERT速度

2 个答案:

答案 0 :(得分:1)

对于选择:

INDEX(a, d)

索引中的第一列(即a)应与“=常量”进行比较。

然后是一个范围,即d > ...

由于OR,其他内容很难索引。但是,它都是相同的变量:e=1 OR e=5 OR e=6 OR e=8 OR e=15,相当于e IN (1, 5, 6, 8, 15)。所以,这更好:

INDEX(a, e, d)

这是因为优化器(在5.6中)可以“跳过”e的索引。也就是说,在所有'='列之后,在''范围'之前,你有一个'IN'。

这是一个“覆盖”指数:

INDEX(a, e, d, c)

可能更好。在庞大和“覆盖”之间存在权衡。要预测它是否会更好是不容易的;此外,对某些价值观可能更好,对其他价值观则更糟。这将是320字节而不是20。

(注意:此索引中的列和其他必须按给定顺序排列。)

more

适用于INSERT

LOAD DATA可能是最好的。但是,如果LOAD中的行数过多,则可能会对SELECTs产生负面影响。同样非常好的是每批100-1000行的批量INSERTs

<强> VARBINARY

那可能是打包的MD5或IPv6?它也可能是BINARY(16)?它并没有像有些人说的那样伤害索引。

<强> InnoDB的

当然,使用InnoDB,而不是MyISAM。

答案 1 :(得分:0)

通过复合或覆盖索引实现最大选择速度。问题是,你的varchars会妨碍你。他们(目前至少有一个)太宽而无法覆盖,但你的整体却没有。因此,请考虑以最常用的方式选择复合索引,例如

key (i1,i2,i2) 

对于一些整体。

要获得最大插入速度,请选择LOAD DATA INFILE,即使在交互式GUI应用的情况下,也可以选择最快的方法。它需要一些工作表配置来引入数据。您需要处理以前存在的数据等概念。并且经常使用特殊的update with a join模式解决方案将数据从工作表中获取到真实表中。事实上,没有绑定循环将实现这种吞吐量。