I have a database in ms-sql-server express 2008 which is accessed with linq-to-sql from the same pc.
(not much concurrent access, but complex queries)
It has several tables and each table can get quite big, to the point where performance of queries, deletes, updates and inserts becomes too slow.
There is one main table projects and almost every other table has
- a direct 1-n relationship with a project
- or an 1-n relationship with a table that has an 1-n relationship with a project,
- or an 1-n relationship with one of these tables and so on.
Selects, deletes, updates and inserts always operate on a single project.
I never need to update entries across different projects or select matching items from 2 projects etc.
Is there some way I can use this fact to increase the performance of the database?
I already have a non-clustered index over the foreign key project_ID wherever applicable.
Is there anything else I can do?
Would partitioning help me, if it were available for sql-express?
edit:
examples of slow queries (paraphrased, most are linq-to-sql queries, for a few deletes i execute the sql directly):
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)
The common point between all my queries is this: they all have a where projectID=XY in there somewhere
All my attempts with indexes or various settings in the DB did not significantly improve performance.
Here is what worked for me in the end:
for this type of query:
Instead of bulk deleting all items matching the criteria, I found a way tht is significantly faster, using
ON DELETE CASCADEupdate items set items.projectID=DummyProjectIDwhere items.projectID=X
AND (items.prop1=a OR items.prop2=b OR items.prop3=c)
For some reason this is much faster than simply deleting the items. Creation of the new project and updating a few 1000 items happens almost instantly, and deleting the project is at least 10 times faster than deleting the items directly.
For these types of queries:
it was much faster to load all itemprops for a project into a dictionary once, and then answer all queries from this local cache. It is not very elegant, and I have to remember to update the cache after each change, but it works.