小编典典

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

sql

在我曾任职的一家前公司中,经验法则是,一个表最多只能有一个索引(允许出现奇怪的异常,并且某些父表几乎包含所有其他表的引用,因此非常频繁地进行更新)。

通常的想法是,维护索引所花费的成本等于或大于获取的成本。

这是真的?这种索引纯粹主义值得吗?

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

关于索引的一般大规模建议是什么?

当前和在上一家公司中,我们都使用SQL Server,因此也欢迎任何特定于产品的准则。


阅读 204

收藏
2021-04-15

共1个答案

小编典典

您需要创建与创建数量一样多的索引。不多不少。它是如此简单。

每个人都“知道”索引会减慢表上的DML语句。但是由于某种原因,实际上很少有人真正去测试它在上下文中的变慢程度。有时我给人的印象是,人们认为添加另一个索引会给插入的每一行增加几秒钟的时间,这使某些虚构的热门用户应该在董事会中做出改变游戏规则的商业折衷。

我想分享一个使用标准MySQL安装程序在2岁的PC上创建的示例。我知道您已标记问题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;

我的时间是:

  • 不含索引的表中1m行:0.45秒
  • 带有1个索引的表中的1m行:1,5秒
  • 1m行进入具有9个索引的表:6,98秒

使用SQL胜于统计和数学,但我想这样想:在表中添加8个索引,总共增加(6,98-1,5)5,48秒。这样,每个索引将为所有1,000,000行贡献0,685秒(5,48
/ 8)。这意味着每个索引每行增加的开销将为0,000000685秒。 有人叫董事会!

总而言之,我想说上述测试案例并不能证明是坏事。它只是表明,今晚,我能够在单个用户环境中的表中插入1,000,000个连续的整数。您的结果
有所不同。

2021-04-15