每个表使用多个索引是危险的吗?

Car*_*ngo 15 sql sql-server

在我曾经工作的前公司中,经验法则是一个表应该只有一个索引(允许奇怪的异常,并且某些父表几乎所有其他表都被引用,因此非常频繁地更新).

通常情况下,索引的成本与获得的成本相同或更高.请注意,此问题与indexed-view-vs-index-on-table不同,因为动机不仅仅是报告.

这是真的?这种指数纯粹主义值得吗?

在你的职业生涯中,你通常会避免使用索引?

关于指数的一般大规模建议是什么?

目前,在最后一家公司,我们使用SQL Server,因此欢迎任何产品特定指南.

Ron*_*nis 40

您需要创建与创建所需数量完全相同的索引.不多也不少.它是如此简单.

每个人都"知道"索引会减慢表上的DML语句.但由于某些原因,很少有人真的费心去测试它在上下文中的"慢"程度.有时我会得到一种印象,即人们认为添加另一个索引会为每个插入的行添加几秒钟,这使得它成为一个改变业务权衡的游戏,一些虚构的热门用户应该在董事会会议室决定.

我想分享一个我刚刚在我2岁的电脑上使用标准MySQL安装创建的示例.我知道您标记了SQL Server的问题,但该示例应该很容易转换.我将1,000,000行插入三个表中.一个表没有索引,一个表有一个索引,一个表有九个索引.

drop table numbers;
drop table one_million_rows;
drop table one_million_one_index;
drop table one_million_nine_index;

/*
|| Create a dummy table to assist in generating rows
*/
create table numbers(n int);

insert into numbers(n) values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

/*
|| Create a table consisting of 1,000,000 consecutive integers
*/   
create table one_million_rows as
    select d1.n + (d2.n * 10)
                + (d3.n * 100)
                + (d4.n * 1000)
                + (d5.n * 10000)
                + (d6.n * 100000) as n
      from numbers d1
          ,numbers d2
          ,numbers d3
          ,numbers d4
          ,numbers d5
          ,numbers d6;


/*
|| Create an empty table with 9 integer columns.
|| One column will be indexed
*/
create table one_million_one_index(
   c1 int, c2 int, c3 int
  ,c4 int, c5 int, c6 int
  ,c7 int, c8 int, c9 int
  ,index(c1)
);

/*
|| Create an empty table with 9 integer columns.
|| All nine columns will be indexed
*/
create table one_million_nine_index(
   c1 int, c2 int, c3 int
  ,c4 int, c5 int, c6 int
  ,c7 int, c8 int, c9 int
  ,index(c1), index(c2), index(c3)
  ,index(c4), index(c5), index(c6)
  ,index(c7), index(c8), index(c9)
);


/*
|| Insert 1,000,000 rows in the table with one index
*/
insert into one_million_one_index(c1,c2,c3,c4,c5,c6,c7,c8,c9)
select n, n, n, n, n, n, n, n, n
  from one_million_rows;

/*
|| Insert 1,000,000 rows in the table with nine indexes
*/
insert into one_million_nine_index(c1,c2,c3,c4,c5,c6,c7,c8,c9)
select n, n, n, n, n, n, n, n, n
  from one_million_rows;
Run Code Online (Sandbox Code Playgroud)

我的时间是:

  • 没有索引的1m行到表中:0,45秒
  • 1m行到表中有1个索引:1.5秒
  • 表格中有1米行,有9个索引:6,98秒

我更喜欢使用SQL而不是统计和数学,但我想是这样的:在我的表中添加8个索引,总计增加了(6,98-1,5)5,48秒.然后,每个索引将为所有1,000,000行贡献0,685秒(5,48/8).这意味着每个索引每行增加的开销将为0,000000685秒.有人打电话给董事会!

总而言之,我想说上面的测试用例并不是一个糟糕的事.它只是表明,今晚,我能够在单个用户环境中将1,000,000个连续整数插入表中.你的结果有所不同.


HLG*_*GEM 8

这完全是荒谬的.首先,您需要多个索引才能正确执行.例如,如果您有主键,则会自动拥有索引.这意味着你不能使用你描述的规则索引任何其他内容.因此,如果您不索引外键,则连接速度会很慢,如果您没有索引where子句中使用的字段,查询仍然会很慢.是的,你可以有太多的索引,因为它们需要额外的时间来插入和更新和删除记录,但不超过一个并不危险,要求系统运行良好.我发现用户可以容忍更长的插入时间,而不是容忍更长的查询时间.

现在例外可能是一个系统每秒从一些自动化设备获取数千个读数.这是一个通常没有索引来加速插入的数据库.但通常这些类型的数据库也不用于读取,而是每天将数据传输到索引的报告数据库.


mar*_*c_s 6

是的,当然 - 表上的索引太多可能比没有索引更糟糕.但是,我认为"每桌最多一个索引"规则没有任何好处.

对于SQL Server,我的规则是:

  • 索引任何外键字段 - 这有助于JOIN,也有利于其他查询
  • 在有意义的情况下索引任何其他字段,例如,当大量密集查询可以从中受益时

找到正确的指数组合 - 权衡加速查询的优点与INSERT,UPDATE,DELETE的额外开销 - 不是一个精确的科学 - 更多的是关于技术诀窍,经验,测量,测量和再次测量.

任何固定的规则都必然会比其他任何东西更具反效力......

关于索引的最佳内容来自Kimberly Tripp-- 索引女王 - 请点击此处的博客文章.