我有一个包含大量行(10K +)的表,主键是GUID.主键是群集的.此表的查询性能非常低.请提供建议,以提高效率.
我在SQL Server 2005中有一个存储过程,当我运行它并查看它的执行计划时,我注意到它正在进行聚簇索引扫描,这使得它的成本为84%.我已经读过,我必须修改一些东西以获得Clustered Index Seek,但我不知道要修改什么.
我会感激任何帮助.
谢谢,
布赖恩
begin transaction;
create table person_id(person_id integer primary key);
insert into person_id values(1);
... snip ...
insert into person_id values(50000);
commit;
Run Code Online (Sandbox Code Playgroud)
这段代码在我的机器上大约需要0.9秒,并创建一个占用392K的db文件.如果我将第二行更改为,则这些数字变为1.4秒和864K
create table person_id(person_id integer nonclustered primary key);
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
我的两个问题是:
详细说来,我有一个包含公司数据的几个非常大(在100-1000万行之间)的数据库.通常,在这样的表中存在大约20-40个公司的数据,每个公司都是由"CompanyIdentifier"(INT)标记的他们自己的"块".此外,每家公司都有大约20个部门,每个部门都有自己的"子块",标有"DepartmentIdentifier"(INT).
经常会发生从表中添加或删除整个"块"或"子块".我的第一个想法是在这些块上使用表分区,但由于我使用的是SQL Server 2008标准版,因此我无权使用它.尽管如此,我所拥有的大多数查询都是在"块"或"子块"上执行而不是在整个表格上执行.
我一直在努力为以下功能优化这些表:
对于1)和2)我没有遇到很多问题.我在关键字段上创建了几个索引(也包含有用的CompanyIdentifier和DepartmentIdentifier),查询运行正常.
但对于3)我一直在努力寻找一个好的解决方案.我的第一个策略是始终禁用索引,批量插入大块并重建索引.这在开始时非常快,但现在数据库中有很多公司,每次重建索引需要很长时间.
目前我的策略已经改为只是在插入时保持索引,因为现在这似乎更快.但我想进一步优化插入速度.
我似乎注意到通过添加在CompanyIdentifier + DepartmentIdentifier上定义的聚簇索引,将新的"块"加载到表中的速度更快.在我放弃这个策略以支持在IDENTITY列上添加聚簇索引之前,有几篇文章向我指出聚簇索引包含在所有其他索引中,因此聚簇索引应该尽可能小.但现在我正在考虑恢复这个旧策略来加速插入.我的问题,这是明智的,还是会在其他领域遇到性能打击?这真的会加速我的插入还是仅仅是我的想象力?
我也不确定在我的情况下是否确实需要IDENTITY列.我希望能够与其他表建立外键关系,但我是否也可以使用类似于CompanyIdentifier + DepartmentIdentifier + [uniquifier]方案的东西?或者它必须是一个表格,分散的IDENTITY数字?
非常感谢任何建议或解释.
database sql-server identity-column clustered-index sql-server-2008
我为SQL SERVER 2005数据库继承了一些数据库创建脚本.
我注意到的一件事是所有主键都创建为NON CLUSTERED索引而不是群集.
我知道每个表只能有一个聚簇索引,并且您可能希望将它放在非主键列上以查询搜索性能等.但是CLUSTERED问题中的表中没有其他索引.
所以我的问题是,除了上述之外,是否有任何技术原因不在主键列上有聚簇索引.
评论"如何减少简单选择查询的响应时间?" 告诉:
"LaunchDate上的数据类型是什么?如果DATETIME或DATETIME2是DATETIME或DATETIME2,则索引不太可能做多,因为它们包含时间部分 - OMG Ponies"
"@OMG - 为什么DateTime列上的Clustered Index不能提高性能?查询是一个范围扫描,它允许快速索引查找,因为所有数据都在顺序块中?半相关... msdn. microsoft.com/en-us/library/ms177416.aspx - 卡尔加里编码器"
"Calgary Coder:DATETIME/2包括时间 - 一个索引,无论是聚簇的还是非聚集的,对于重复次数而不是范围的日期都是有用的. - OMG Ponies"
我在DATETIME类型列上创建了一个带有聚簇索引的测试表,LaunchDate并观察索引查找类似于上述问题中引用的查询:
SELECT COUNT(primaryKeyColumn)
FROM MarketPlan
WHERE LaunchDate > @date
Run Code Online (Sandbox Code Playgroud)
而不是表或索引扫描.
为什么DateTime列上的聚簇索引不会提高性能?
为什么索引不是可能做得太多,如果它DATETIME或DATETIME2因为它们包括时间部分?
我很欣赏一个脚本,说明DATETIME列的索引不会提高性能.
更新:另外,OMG没有暗示对指数DATE型列将是有益的,但不DATETIME和DATETIME2?
sql-server indexing performance database-design clustered-index
我有一个超过2000万行的表,当我这样做时:
DELETE [Table] WHERE ID = ?
Run Code Online (Sandbox Code Playgroud)
这需要40秒以上.ID列是群集的.
这是你可以期待的吗?还是可以优化这个?
从EF6.1开始,我们可以在属性上指定聚簇索引
public class Person
{
[Index(IsClustered = true, IsUnique = true)]
public long UserName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
但是这个Index属性现在似乎不在EF Core中?在EF Core中你是如何实现这一目标的?
我正在按照 Azure 门户中的查询洞察刀片的建议向 SQL Azure 数据库添加一个新索引,该索引使用该ONLINE=ON标志。SQL 看起来像这样:
CREATE NONCLUSTERED INDEX [IX_MyIndex] ON
[Customers].[Activities] ([CustomerId])
INCLUDE ([AccessBitmask], [ActivityCode], [DetailsJson],
[OrderId], [OperationGuid], [PropertiesJson], [TimeStamp])
WITH (ONLINE = ON)"
Run Code Online (Sandbox Code Playgroud)
但是,我们也需要将这个相同的索引添加到我们本地的开发数据库中,它们只是localdb不支持该ONLINE=ON选项的实例,导致以下错误。
Online index operations can only be performed in Enterprise edition of SQL Server.
Run Code Online (Sandbox Code Playgroud)
我的问题是 - 有没有办法编写这个 SQL 索引创建语句,ONLINE=ON 如果可用,它将使用,但在不支持它的数据库上仍然成功?
我的模型中有两张桌子:
1)拥有者:
OwnerName
Run Code Online (Sandbox Code Playgroud)
2)汽车
OwnerKey
CarName
CarPrice
Run Code Online (Sandbox Code Playgroud)
这里在Owner表中创建一行时,我还为该所有者Car table添加了Cars.因此,特定所有者的所有汽车都按顺序存储在Car表中.现在,如果我想询问是否应该使用集群索引?一旦保存了特定车主的车辆,则不会为该车主添加任何车辆,也不会删除任何车辆,只需更改价格.我应该怎样做才能加快访问速度?以及如何通过django实现集群索引?
clustered-index ×10
sql-server ×5
performance ×4
database ×2
indexing ×2
sql ×2
django ×1
guid ×1
mysql ×1
primary-key ×1
sqlite ×1
t-sql ×1