我已经有点知道这个问题的答案了,但我总觉得我需要更多地了解这个话题。
我的基本理解是,一般来说,仅包含您可能在任何给定时间查询/排序的所有字段的单个索引不太可能有用,但我已经看到了这种类型的事情。就像有人想的那样,“好吧,如果我们把所有这些东西都放在一个索引中,数据库就可以使用它来找到它需要的东西”,而从未见过一些正在运行的实际查询的执行计划。
想象一个像这样的表:
id int pk/uid
name varchar(50)
customerId int (foreign key)
dateCreated datetime
Run Code Online (Sandbox Code Playgroud)
我可能会看到一个包含name,customerId和dateCreated字段的索引。
但我的理解是这样的索引不会在查询中使用,例如:
SELECT [id], [name], [customerId], [dateCreated]
FROM Representatives WHERE customerId=1
ORDER BY dateCreated
Run Code Online (Sandbox Code Playgroud)
对于这样的查询,在我看来,更好的主意是包含customerId和dateCreated字段的索引,该customerId字段是“第一”。这将创建一个索引,该索引将以这样一种方式组织数据,以便该查询可以快速找到它需要的内容 - 按照它需要的顺序。
我看到的另一件事,也许和第一件事一样频繁,是每个字段的单独索引;所以,每一个上name,customerId和dateCreated领域。
与第一个例子不同,这种安排在我看来有时至少是部分有用的。查询的执行计划可能会显示至少它使用 上的索引customerId来选择记录,但它没有使用带有dateCreated字段的索引对它们进行排序。
我知道这是一个广泛的问题,因为对任何特定表集的任何特定查询的具体答案通常是查看执行计划所说的它将要做什么,否则将表和查询的细节纳入帐户。另外,我知道这取决于查询的运行频率,而不是为其维护特定索引的开销。
但我想我要问的是作为索引的一般“起点”,为特定的、经常提取的查询和 WHERE 或 ORDER BY 子句中的字段设置特定索引的想法有意义吗?
我们的数据库由许多表组成,其中大多数使用整数代理键作为主键。这些主键中约有一半位于标识列上。
数据库开发始于 SQL Server 6.0。
从一开始就遵循的规则之一是,避免根据递增键创建聚集索引,正如您在这些索引优化技巧中找到的那样。
现在使用 SQL Server 2005 和 SQL Server 2008,我强烈的印象是情况发生了变化。同时,这些主键列是表的聚集索引的完美首选。
我在 Windows 服务器上的 SQL Server 2008 上有一个数据库,我想将所有数据移动到 Ubuntu 服务器上的 MySQL 数据库。我尝试将 SQL Server 导入和导出向导与 MySQL ODBC 驱动程序一起使用,它可以正确访问两个数据库,但包含类型转换规范的 xml 文件不存在,而且规范太有限,我无法正确创建它们。有谁知道如何创建类型转换文件或从哪里获得更好的工具来传输这些数据?
由于 varchar 占用的磁盘空间与字段的大小成正比,有什么理由我们不应该总是将 varchar 定义为最大值,例如varchar(8000)在 SQL Server 上?
在创建表上,如果我看到有人在做varchar(100)我应该告诉他们不你错了你应该做什么varchar(8000)?
BOL 中的建议相当模糊:
根据需要经常备份 master 以充分保护数据以满足您的业务需求。我们建议定期备份计划,您可以在大量更新后补充额外的备份。
如果你进一步冒险,你会发现这些细节:
导致 master 更新和需要进行备份的操作类型包括以下内容:
- 创建或删除用户数据库。
- 如果用户数据库自动增长以容纳新数据,
master 不会受到影响。- 添加或删除文件和文件组。
- 添加登录或其他与登录安全相关的操作。
- 数据库安全操作,例如向数据库添加用户,不影响master。
- 更改服务器范围或数据库配置选项。
- 创建或删除逻辑备份设备。
- 为分布式查询和远程过程调用 (RPC) 配置服务器,例如添加链接服务器或远程登录。
因此,如果我们所有的登录都是通过 Windows 组添加的,并且我们不对数据库进行任何其他更改,这是否意味着对 master 进行一次备份就足够了?
如果不是,master 数据库的标准备份间隔是多少?
在阅读了慢 SQL 查询后,不确定如何优化,这让我想到了查询的总体性能。当然,我们需要第一个表的结果(当其他表被连接时)在连接之前尽可能小(这个问题的内部连接),以使我们的查询更快一点。
例如,应该这样:
SELECT *
FROM ( SELECT * FROM table1 WHERE col = @val ) t
INNER JOIN table2 ON col = col2
Run Code Online (Sandbox Code Playgroud)
比以下更好/更快:
SELECT *
FROM table1
INNER JOIN table2 ON col = col2
WHERE table1.col = @val
Run Code Online (Sandbox Code Playgroud)
我的理论如下(这可能不是正确的实现,我试图从我读过的 SQL Server 2008 内部书籍(MSFT Press)中记住):
因此,如果在上面的语句 #1 中,表较小,则 SQL 引擎在形成笛卡尔积时要做的工作较少。然后,当您到达 where 语句时,您将拥有一个简化的结果集,可从中过滤内存。
我可能离目标太远了,这是不真实的。就像我说的,这是一个理论。
你的意见?
注意:我刚刚想到这个问题,还没有机会自己进行任何测试。
注2:标记为SQL Server的,因为我不知道任何关于MySQL等的实施,请随时接听/评论反正
我注意到一些 DBA 非常频繁地重新启动 SQL Server,有时甚至每晚都重新启动。我相信他们这样做是为了释放一些内存,或者也可能是为了加快查询速度。我知道在重新启动后必须重新编译查询计划,但即使包括这一点,我也想知道这种做法是否有净收益。
每天重新启动 SQL Server 会使其运行得更快吗?
因此,我们有一个客户站点抱怨性能严重下降。我看了一眼,很明显问题是因为别人 (grrrr) 设计了一个表,其中包含大约 2000 万多条记录,而没有聚集索引。
现在我想在该表上创建一个聚集索引 - 但在我的测试环境中 create index命令已经运行了一个小时,但仍未完成。客户站点是一个 24/7 全天候工作的车间,在我创建索引时无法承受一个小时的停机时间。
是否有一些不那么强力的创建索引的方法可以快速完成工作,或者以某种不会在服务器繁忙时完全杀死服务器性能的聪明方式来完成?
我们正在使用 SQL Server 企业版。
我们在 SQL 2005 上有一个生产数据库服务器。一切正常运行了一段时间,但几周后我们看到性能显着下降。只有重新启动 SQL Server 才能使性能恢复正常。
一些背景:
我们在非高峰时间尝试了几件事: - 运行 DBCC DROPCLEANBUFFERS(带有 CHECKPOINT)以清除数据缓存。它没有任何效果,也不会清除任何 RAM 使用量)。- 运行 FREEPROCCACHE 和 FREESYSTEMCACHE 以清除查询计划和存储的 proc 缓存。没有效果。
显然,在活跃的生产环境中重新启动 SQL Server 并不理想。我们缺少一些东西。还有其他人经历过这个吗?
更新:2012 年 4 月 28 日 仍在与这个问题作斗争。我已将 SQL Server 的内存降低到 10 GB,只是为了排除与操作系统的任何争用。我越来越接近缩小范围,但下一步需要一些帮助。
这是我发现的,重新启动 SQL Server 后,页面文件在 12.3 GB 和 12.5 GB 之间徘徊。它会保持这种状态好几天。服务器线程总数将在 850 到 930 之间挂起 - 在几天内也保持稳定和一致(sqlserver 稳定在 55 到 85 之间,具体取决于流量)。
然后,有一个“事件”。我不知道事件是什么,我在日志中看不到它,也看不到在星期几或它发生的时间有任何一致的东西,但是他的页面文件突然跳到了 14.1 或 14.2 …
有没有办法在键入查询时暂时禁止 SQL Server Management Studio 的自动完成?我不想完全禁用自动完成功能,只是说在输入特定单词时按住某个键,以免妨碍到它。
例如说我有以下查询
SELECT Foo, Foo2 FROM SomeTable
Run Code Online (Sandbox Code Playgroud)
当我输入Foo并点击空格键时,SQL Server Management Studio 的自动完成开始并完成Foo到FooBar.
sql-server ×10
performance ×3
index ×2
backup ×1
join ×1
maintenance ×1
migration ×1
mysql ×1
ssms ×1
varchar ×1