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。
     

  • 相关阅读:
    LeetCode Binary Tree Inorder Traversal
    LeetCode Populating Next Right Pointers in Each Node
    LeetCode Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode Reverse Linked List II
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Pascal's Triangle
    Palindrome Construct Binary Tree from Preorder and Inorder Traversal
    Pascal's Triangle II
    LeetCode Word Ladder
    LeetCode Binary Tree Zigzag Level Order Traversal
  • 原文地址:https://www.cnblogs.com/unruledboy/p/57714.html
Copyright © 2011-2022 走看看