2010-03-08 78 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)