0

我有一個數據庫在ms-sql-server express 2008中,它可以從同一臺PC的linq-to-sql進行訪問。 (沒有太多的併發訪問,但複雜的查詢)爲'foreign_key = x'查詢增加數據庫性能

它有幾個表,每個表可以變得非常大,以至於查詢,刪除,更新和插入的性能變得太慢。

有一個主表項目和幾乎所有其他表有

  • 與項目
  • 或一個表,有一個1的1-N關係的直接1-n的關係n與項目的關係,
  • 或與這些表格之一的1-n關係等。

選擇,刪除,更新和插入始終對單個項目進行操作。 我從來不需要更新不同項目的條目或從2個項目中選擇匹配的項目等。

有沒有什麼方法可以用這個事實來提高數據庫的性能?

只要適用,我已經在外鍵project_ID上有一個非聚集索引。

還有什麼我可以做的嗎? 分區幫助我,如果它可用於sql-express?


編輯:

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) 

的公共點:慢查詢(轉述,最多的是LINQ到SQL查詢,針對一些刪除我直接執行SQL)的

例子我所有的查詢之間是這樣的:他們都有一個where projectID=XY在那裏

+0

您可以舉一個慢查詢的例子,以及相關的模式嗎? – mwigdahl 2012-04-27 19:30:17

+0

你有維護工作嗎? – 2012-04-27 21:06:52

+0

re:查詢2 - 連接中的列上是否有索引?那麼WHERE子句中的列呢?查詢3 - 表中有多少個字段(使用SELECT *是一種不好的做法 - 只選擇你需要的) - 表格是否被標準化?另外,請記住任何僅當[有選擇性](http://www.akadia.com/services/ora_index_selectivity.html) – 2012-04-27 21:34:31

回答

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. 刪除虛擬項目。由於級聯刪除已啓用,因此也刪除了這些項目。

由於某些原因,這比簡單地刪除項目要快得多。創建新項目並更新幾千項目幾乎立即發生,並且刪除項目至少比直接刪除項目快10倍。


對於這些類型的查詢:

select top 1 itemprops ... 

這是更快,爲項目的所有itemprops加載到一個字典一次,然後從這個本地緩存回答所有的問題。這不是非常優雅,我必須記住在每次更改後更新緩存,但它的工作原理。

0

對於第一個語句(刪除),您可以創建一個新的非聚集索引,其中包括兩個您的連接字段:

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

同樣適用於最後的SELECT查詢。優化器應該認識到,這個索引會產生更好的計劃並使用它 - 檢查查詢計劃,如果沒有,查看索引提示。您也可以刪除OR,只做三個單獨的刪除查詢。

在最後兩個,請確保您使用ORDER BY子句,以便查詢知道你想要什麼TOP。中間的一個很困難:缺少對所有內容的索引(再次檢查查詢計劃),您可能想要查看是否可以避免加入該「名稱」字段並嘗試使用ID。我知道這並非總是可行,但SQL比數字比字符串更好。

+0

我還沒有使用過分區,但是我被告知它只適用於非常大的表,比如1M +行。 [Here's](http://www.sqlservercentral.com/articles/partition/64740/)上的一篇優秀文章。 – 2012-04-28 00:14:02