(MS SQL)如何实现相关文章功能(多关键字匹配)改进版
2004-10-28 13:12 灵感之源 阅读(3426) 评论(12) 收藏 举报大家先看一则新闻:http://blog.csdn.net/robertb9527/archive/2004/10/25/150117.aspx vb.net的位置:我觉得这似乎有点不对径,怎么可能fortron等这些老掉牙的语言这么高,竟然比VB.NET还高。 
这是(MS SQL)如何实现相关文章功能(多关键字匹配)的改进版,参考了吕震宇和msolap 的建议之后, 
解决方案2:原来的做法是文章表和关键字表,关键字表可能会存在大量重复的关键字,所以采用中间表,而关键字不再重复。 
设计:首选要做的是在原有文章表(Details)的基础上建立关键字表(DetailKeywords),字段包括ItemID(主键)和Keyword(关键字),还有中间表DetailsKeywords,包括DetailID(文章ID)和KeywordID(关键字ID)。以下是主要存储过程: 
□UpdateRelatedDetails:更新关键字 
 CREATE procedure dbo.UpdateRelatedDetails
CREATE procedure dbo.UpdateRelatedDetails 
 
 
 @DetailID INT,
@DetailID INT, 
 @Keywords NVARCHAR(500)
@Keywords NVARCHAR(500) 
 
 
 AS
AS 
 
 
 SET NOCOUNT ON
SET NOCOUNT ON 
 
 
 EXEC DeleteRelatedDetails @DetailID
EXEC DeleteRelatedDetails @DetailID 
 
 
 DECLARE @I INT
DECLARE @I INT 
 DECLARE @Keyword NVARCHAR(50)
DECLARE @Keyword NVARCHAR(50) 
 DECLARE @KeywordID INT
DECLARE @KeywordID INT 
 
 
 SET @Keywords=REPLACE(@Keywords,',', ',')
SET @Keywords=REPLACE(@Keywords,',', ',') 
 SET @Keywords=REPLACE(@Keywords,';', ',')
SET @Keywords=REPLACE(@Keywords,';', ',') 
 SET @Keywords=RTRIM(LTRIM(@Keywords))
SET @Keywords=RTRIM(LTRIM(@Keywords)) 
 
 
 SET @I=CHARINDEX(',', @Keywords)
SET @I=CHARINDEX(',', @Keywords) 
 
 
 WHILE @I>=1
WHILE @I>=1 
 BEGIN
    BEGIN 
 SET @Keyword=LEFT(@Keywords, @I-1)
        SET @Keyword=LEFT(@Keywords, @I-1) 
 
         
 EXEC AddRelatedDetailKeyword @DetailID, @Keyword
        EXEC AddRelatedDetailKeyword @DetailID, @Keyword 
 
 
 SET @Keywords=SUBSTRING(@Keywords, @I+1,LEN(@Keywords)-@I)
        SET @Keywords=SUBSTRING(@Keywords, @I+1,LEN(@Keywords)-@I) 
 SET @I=CHARINDEX(',', @Keywords)
        SET @I=CHARINDEX(',', @Keywords) 
 END
    END 
 
 
 IF @Keywords<>''
IF @Keywords<>'' 
 EXEC AddRelatedDetailKeyword @DetailID, @Keywords
    EXEC AddRelatedDetailKeyword @DetailID, @Keywords 
 
 
 SET NOCOUNT OFF
SET NOCOUNT OFF 
 GO
GO 
 
 
   
□AddRelatedDetailKeyword:添加单个关键字 
 CREATE procedure dbo.AddRelatedDetailKeyword
CREATE procedure dbo.AddRelatedDetailKeyword 
 
 
 @DetailID INT,
@DetailID INT, 
 @Keyword NVARCHAR(50)
@Keyword NVARCHAR(50) 
 
 
 AS
AS 
 
 
 SET NOCOUNT ON
SET NOCOUNT ON 
 
 
 DECLARE @KeywordID INT
DECLARE @KeywordID INT 
 
 
 SELECT @KeywordID=ItemID FROM DetailKeywords WHERE Keyword=@Keyword
SELECT @KeywordID=ItemID FROM DetailKeywords WHERE Keyword=@Keyword 
 
 
 IF @KeywordID IS NULL
IF @KeywordID IS NULL 
 BEGIN
    BEGIN 
 INSERT INTO DetailKeywords (Keyword) VALUES(@Keyword)
        INSERT INTO DetailKeywords (Keyword) VALUES(@Keyword) 
 SET @KeywordID=IDENT_CURRENT('DetailKeywords')
        SET @KeywordID=IDENT_CURRENT('DetailKeywords') 
 END
    END 
 INSERT INTO DetailsKeywords (DetailID, KeywordID) VALUES(@DetailID, @KeywordID)
INSERT INTO DetailsKeywords (DetailID, KeywordID) VALUES(@DetailID, @KeywordID) 
 
 
 SET NOCOUNT OFF
SET NOCOUNT OFF 
 GO
GO 
 
 
   □DeleteRelatedDetails:删除之前的关键字,存在点问题
 CREATE PROCEDURE dbo.DeleteRelatedDetails
CREATE PROCEDURE dbo.DeleteRelatedDetails 
 
 
 @DetailID INT
@DetailID INT 
 
 
 AS
AS 
 
 
 SET NOCOUNT ON
SET NOCOUNT ON 
 
 
 --这里还有其它东西没有判断和删除
--这里还有其它东西没有判断和删除 
 
 
 DELETE FROM DetailsKeywords WHERE DetailID=@DetailID
DELETE FROM DetailsKeywords WHERE DetailID=@DetailID 
 
 
 SET NOCOUNT OFF
SET NOCOUNT OFF 
 GO
GO 
 
 
   □GetRelatedDetails:根据某文章ID获取相关文章
 CREATE procedure dbo.GetRelatedDetails
CREATE procedure dbo.GetRelatedDetails 
 
 
 @DetailID INT
@DetailID INT 
 
 
 AS
AS 
 
 
 SELECT DISTINCT d.ItemID, d.Subject FROM Details d, DetailKeywords k, DetailsKeywords s
SELECT DISTINCT d.ItemID, d.Subject FROM Details d, DetailKeywords k, DetailsKeywords s 
 WHERE d.ItemID = s.DetailID AND k.ItemID=s.KeywordID AND d.ItemID<>@DetailID
 WHERE d.ItemID = s.DetailID AND k.ItemID=s.KeywordID AND d.ItemID<>@DetailID 
 GO
GO 
 
 
   
我贴一下性能比较,环境是30万条记录,机器是PIII 800+300多内存,硬盘是7200转: 
--第1种,两表情况 
--select a.* from Article a,ArtKey2 b 
--where a.ArtID=b.ArtID and b.KeyValue='科技9' 
--第2种,三表情况 
--select a.* from Article a,ArtKey1 b, 
--    (select KeyID from KeyValue where KeyValue='科技9') c 
--where a.ArtID=b.ArtID and b.KeyID=c.KeyID 
--第3种,三表情况 
--select * from Article where ArtID in 
--(select ArtID from ArtKey1 where KeyID in 
--    (select KeyID from KeyValue where KeyValue='科技9')) 
优化Sql语句主要是通过在“执行计划”图所显示的IO成本,以及cpu成本来分析执行效率。在SQL查询分析器的执行计划中,IO成本+CPU成本=本步成本。 
三种SQL语句在同一批处理中的执行分析结果: 
1、占14.22%,实际执行成本为2.96。 
2、占43.08%,实际执行成本为9.96。 
3、占42.70%,实际执行成本为8.88。 
第一种执行成本远小于后者,且执行计划也比后者简洁得多,显然第一种要优于其它两种。执行计划简洁不是优越的标准,但SQL语句写得不够简洁,通常是为了满足业务需求不得已写出复杂语句。第2种与种3种的执行计划只是在最后一步不同,前者是inner join,后者是Right Semi Join。 
  
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号