zoukankan      html  css  js  c++  java
  • (MS SQL)如何实现相关文章功能(多关键字匹配)改进版

    大家先看一则新闻: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

    @DetailID INT,
    @Keywords 
    NVARCHAR(500)

    AS

    SET NOCOUNT ON

    EXEC DeleteRelatedDetails @DetailID

    DECLARE @I INT
    DECLARE @Keyword NVARCHAR(50)
    DECLARE @KeywordID INT

    SET @Keywords=REPLACE(@Keywords,''',')
    SET @Keywords=REPLACE(@Keywords,''',')
    SET @Keywords=RTRIM(LTRIM(@Keywords))

    SET @I=CHARINDEX(',', @Keywords)

    WHILE @I>=1
        
    BEGIN
            
    SET @Keyword=LEFT(@Keywords, @I-1)
            
            
    EXEC AddRelatedDetailKeyword @DetailID, @Keyword

            
    SET @Keywords=SUBSTRING(@Keywords, @I+1,LEN(@Keywords)-@I)
            
    SET @I=CHARINDEX(',', @Keywords)
        
    END

    IF @Keywords<>''
        
    EXEC AddRelatedDetailKeyword @DetailID, @Keywords

    SET NOCOUNT OFF
    GO


    □AddRelatedDetailKeyword:添加单个关键字

    CREATE procedure dbo.AddRelatedDetailKeyword

    @DetailID 
    INT,
    @Keyword 
    NVARCHAR(50)

    AS

    SET NOCOUNT ON

    DECLARE @KeywordID INT

    SELECT @KeywordID=ItemID FROM DetailKeywords WHERE Keyword=@Keyword

    IF @KeywordID IS NULL
        
    BEGIN
            
    INSERT INTO DetailKeywords (Keyword) VALUES(@Keyword)
            
    SET @KeywordID=IDENT_CURRENT('DetailKeywords')
        
    END
    INSERT INTO DetailsKeywords (DetailID, KeywordID) VALUES(@DetailID, @KeywordID)

    SET NOCOUNT OFF
    GO

    □DeleteRelatedDetails:删除之前的关键字,存在点问题
    CREATE PROCEDURE dbo.DeleteRelatedDetails

    @DetailID 
    INT

    AS

    SET NOCOUNT ON

    --这里还有其它东西没有判断和删除

    DELETE FROM DetailsKeywords WHERE DetailID=@DetailID

    SET NOCOUNT OFF
    GO

    □GetRelatedDetails:根据某文章ID获取相关文章
    CREATE procedure dbo.GetRelatedDetails

    @DetailID INT

    AS

    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
    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。
     

  • 相关阅读:
    指令
    linux学习之多高并发服务器篇(三)
    linux学习之高并发服务器篇(二)
    linux学习之多高并发服务器篇(一)
    Linux学习之socket编程(二)
    Linux学习之socket编程(一)
    myeclipse中如何修改Servlet模板_day01
    Properties的使用以及配置文件值的获取
    Sql_Server中如何判断表中某字段是否存在
    微博开发流程-01
  • 原文地址:https://www.cnblogs.com/unruledboy/p/57714.html
Copyright © 2011-2022 走看看