sql - 每个表使用多个索引是否危险?

标签 sql sql-server

在我工作过的一家前公司中,经验法则是一个表不应有超过一个索引(允许奇怪的异常(exception),并且某些父表保存对几乎所有其他表的引用,因此更新非常频繁) )。

这个想法是,索引的维护成本通常与它们的 yield 相同或更高。请注意,这个问题与indexed-view-vs-indexes-on-table不同。因为动机不仅仅是报告。

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

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

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

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

最佳答案

您需要创建与需要创建的索引数量完全相同的索引。不多也不少。就这么简单。

每个人都“知道”索引会减慢表上的 DML 语句的速度。但由于某种原因,很少有人真正费心去测试它在他们的环境中变得有多“慢”。有时我的印象是,人们认为添加另一个索引会给每个插入的行增加几秒钟的时间,从而使其成为一个改变游戏规则的业务权衡,一些虚构的热门用户应该在董事会 session 室中决定。

我想分享一个我刚刚在我的 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;

我的时间安排是:

  • 在没有索引的情况下将 100 万行放入表中:0.45 秒
  • 将 100 万行放入具有 1 个索引的表中:1.5 秒
  • 将 100 万行放入具有 9 个索引的表中:6.98 秒

与统计和数学相比,我更擅长 SQL,但我认为: 向我的表添加 8 个索引,总共增加了 (6,98-1,5) 5,48 秒。每个索引将为所有 1,000,000 行贡献 0,685 秒 (5,48/8)。这意味着每个索引每行增加的开销为 0,000000685 秒。 有人调用董事会!

总之,我想说的是,上面的测试用例并没有证明是狗屎。它只是表明今晚我能够在单用户环境中的表中插入 1,000,000 个连续整数。您的结果将会有所不同。

关于sql - 每个表使用多个索引是否危险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4377525/

相关文章:

sql - 如何在 SQL Server 中使用变量指定文件组

java - [Microsoft][ODBC 驱动程序管理器] 无效字符串或缓冲区长度异常

sql - 提高 PostgreSQL 数组查询的性能

sql - 排除验证两个条件的记录

c# - 使用 Dapper 进行多映射查询

c# - 调用存储过程返回 30 个字符中的 1 个

mysql - 将外键从现有表添加到现有表时出错

c# - 在 SQL 或 C# 中对列求和

sql - INSERT INTO 使用子查询和一些操作

.net - 登录前握手期间的 SqlException