2010-03-08 113 views
2

我有一個連接刪除與另一個表匹配的行,但連接字段必須是大型varchar(250個字符)。我知道這並不理想,但我想不出更好的辦法。這裏是我的查詢:在varchar字段超時的SQL連接

DELETE P 
FROM dbo.FeedPhotos AS P 
INNER JOIN dbo.ListingPhotos AS P1 ON P.photo = P1.feedImage 
INNER JOIN dbo.Listings AS L ON P.accountID = L.accountID 
WHERE P.feedID = @feedID 

這個查詢是不斷超時即使有不到1000行的ListingPhotos表。

任何幫助,將不勝感激。

+0

是那裏'P.photo'和'P1.feedImage'任何指標?這些肯定會有所幫助...... –

回答

3

我可能會通過刪除這一行開始,因爲它似乎並沒有被做任何事情:

INNER JOIN dbo.Listings AS L ON P.accountID = L.accountID 

有可能不是很多行中ListingPhotos,但如果有Listings中有很多行,那麼連接將不會被優化。

同時檢查您的索引,因爲任何連接在沒有適當索引的情況下一定會很慢。儘管您通常應儘量避免加入字符字段,但這通常表示數據未正確標準化。

+0

如果它是自然鍵並且您沒有使用代理鍵,那麼加入varchar是可以接受的(問Joe Celko :-)。您必須在varchar列上添加唯一約束或索引(如果它是唯一值並且您選擇了一個int標識作爲PK以保持數據完整性) – gbn

+0

@gbn:如果您的自然密鑰爲250個字符,那麼是時間了代孕;在多個索引的'INSERT' /'UPDATE' /'DELETE'性能命中和一個長度超過8個字節的關鍵字的'SELECT'性能命中之間存在折衷,但250的另一側柵欄。另外,我不相信Joe Celko正確地告訴我一天的時間。 :P – Aaronaught

+0

同意以上所有...... – gbn

0

只需添加一個index

CREATE INDEX idx_feedPhotos_feedid 
    ON dbo.FeedPhotos (feedId) 
1

我會考慮:

  • 重寫使用存在。如果一個行發現更可靠然後依靠JOIN可能有更多的中間行(這是什麼Aaronaught說)這將停止處理

  • 確保所有數據類型匹配正是。在長度或類型的所有差異將意味着沒有索引將被用於

    其中
  • 講,你對feedid,照片和ACCOUNTID指數(粗略估計)?

喜歡的東西:

DELETE 
    P 
FROM 
    dbo.FeedPhotos AS P 
WHERE 
    P.feedID = @feedID 
    AND 
    EXISTS (SELECT * FROM 
      dbo.ListingPhotos P1 
      WHERE P.photo = P1.feedImage) 
    AND 
    EXISTS (SELECT * FROM 
      dbo.Listings L 
      WHERE P.accountID = L.accountID)