0

假设您有一个查询,例如,

select ID, REGION, START, END from COORD_SYSTEM 
where REGION=? and TYPE=? and START >= ? and END <= ?;

假设这张表有大约 50,000 行。REGION 列有 500 个不同的值,TYPE 列有 50 个不同的值。ID 列是主键。

索引表的最佳方法是什么?由于 >= 和 <= 符号,我不太确定是否可以实现覆盖索引。这里有几个选项:

  1. 在 COORD_SYSTEM (REGION, TYPE) 上创建索引
  2. 在 COORD_SYSTEM (REGION, TYPE, START) 上创建索引
  3. 在 COORD_SYSTEM (REGION, TYPE, START, END) 上创建索引

更新 - 这是解释语句:

          id: 1
  select_type: SIMPLE
        table: COORD_SYSTEM
         type: range
possible_keys: indx_A
          key: indx_A
      key_len: 50
          ref: NULL
         rows: 590
        Extra: Using where
1 row in set (0.00 sec)
4

3 回答 3

1

没有理由不能将覆盖索引与范围运算符一起使用。挑战(对于非覆盖索引)是优化器可能认为如果您的范围很大,则完全扫描可能会导致更少的页面读取,并且索引不会用于您的某些查询。类似地,对于某些参数值,如果覆盖索引并不比扫描某些参数集好多少,优化器可能会选择进行全扫描。

因此,鉴于问题中的描述,实际上不可能为所有情况提供最佳解决方案。

我倾向于做这样的事情是:

  • 创建数据库的副本
  • 猜猜哪个索引可以完成这项工作,并创建该索引。
  • EXPLAIN具有不同大小范围的几个查询(如果您没有覆盖查询,则更多范围需要更多 I/O 才能返回表数据,因此您应该尝试常见范围大小和异常值)
  • 删除索引并尝试另一个,可能使用不同的覆盖索引,列的顺序不同

您甚至可以选择使用不同顺序的字段创建两个或更多覆盖索引,假设您运行此查询的次数比相应INSERT的 s 或UPDATEs 多得多,并且索引的大小不是磁盘空间使用的一个因素。

于 2013-08-12T08:17:17.323 回答
1

您可以将索引视为按索引列中的值对行进行预排序的一种方式。索引可用于与>=<=以与 相同的方式进行比较=

您的选项 3可能WHERE是最好的索引,因为只需查看索引即可检查所有条件。它是否真的是最佳索引取决于您的数据集,因为例如,如果您的大多数end记录WHERE end <= ?的优化器可以决定不使用该字段的索引,因为它会导致没有“投资回报”的开销)

于 2013-08-12T08:14:11.467 回答
0

您正在寻找的是BETWEEN命令,您不需要 START 和 END 。您只需 1 个表格行即可。

SELECT ID, REGION, START, END from COORD_SYSTEM WHERE REGION=? and TYPE=? BETWEEN 100 and 200;
于 2013-08-12T08:21:43.453 回答