增加'foreign_key = x'查询的db性能

时间:2012-04-27 19:23:12

标签: sql-server performance sql-server-2008 foreign-keys sql-server-express

我在ms-sql-server express 2008中有一个数据库,可以使用同一台PC上的linq-to-sql访问。 (没有多少并发访问,但复杂的查询)

它有几个表,每个表都可以变得非常大,以至于查询,删除,更新和插入的性能变得太慢。

有一个主表项目,几乎所有其他表都有

  • 与项目的直接1-n关系
  • 或与项目具有1-n关系的表的1-n关系,
  • 或与这些表之一的1-n关系,依此类推。

选择,删除,更新和插入始终在单个项目上运行。 我永远不需要更新不同项目的条目或从2个项目中选择匹配的项目等。

有什么方法可以用这个事实来提高数据库的性能吗?

我已经在适用的外键project_ID上有一个非聚集索引。

还有什么我可以做的吗? 分区可以帮助我,如果它可用于sql-express吗?


编辑:

慢查询的例子(转述,大多数是linq-to-sql查询,对于一些删除我直接执行sql):

  delete from items 
  where items.projectID=X 
  AND (items.prop1=a OR items.prop2=b OR items.prop3=c)
  (deletes a few 1000 items, fast when database is empty, slow when lots of other projects exist)

  select top 1 itemprops 
  from itemprops 
  inner join items on items.id = itemprops.itemid 
  inner join project on item.projectid=project.id 
  inner join modes on itemprops.modeId = mode.id
  where item.name = X and project.id = Y and mode.name = z
  (find a certain itemprop corresponding to an item and a mode)


  select top 1 * from foo where projectID=x and name=Y and type=z
  (nonclustered index on projectID + name + type exists)

我所有查询之间的共同点是:他们在某处都有where projectID=XY

2 个答案:

答案 0 :(得分:0)

对于第一个语句(删除),您可以创建一个包含两个连接字段的新的非聚集索引:

CREATE NONCLUSTERED INDEX <MeaningfulIndexName>
ON Items (ProjectID)
INCLUDE (Prop1, Prop2, Prop3)

最后一个SELECT查询也是如此。优化器应该意识到这个索引将产生更好的计划并使用它 - 检查查询计划,如果没有,请查看索引提示。您也可以删除OR,只需执行三个单独的删除查询。

在最后两个中,确保使用ORDER BY子句,以便查询知道您想要的TOP。中间的一个很难:没有索引所有内容(再次检查查询计划),您可能想看看是否可以避免加入该“名称”字段并尝试使用ID。我知道并不总是可行,但SQL在比较数字而不是字符串方面更胜一筹。

答案 1 :(得分:0)

我在数据库中使用索引或各种设置的所有尝试都没有显着提高性能。

这最终对我有用:


用于此类查询:

 delete from items 
 where items.projectID=X 
 AND (items.prop1=a OR items.prop2=b OR items.prop3=c)

我没有批量删除符合条件的所有项目,而是使用ON DELETE CASCADE

找到了一种明显更快的方式
  1. 创建一个新的虚拟项目
  2. 更新应删除的所有项目:  update items set items.projectID=DummyProjectID where items.projectID=X AND (items.prop1=a OR items.prop2=b OR items.prop3=c)
  3. 删除虚拟项目。由于启用了级联删除,因此也删除了项目。
  4. 出于某种原因,这比简单地删除项目要快得多。创建新项目并更新几千个项目几乎立即发生,删除项目至少比直接删除项目快10倍。


    对于这些类型的查询:

     select top 1 itemprops ...
    

    将项目的所有itemprops加载到字典中一次,然后回答来自此本地缓存的所有查询要快得多。它不是很优雅,我必须记住每次更改后更新缓存,但它可以工作。