大家先看一则新闻:http://blog.csdn.net/robertb9527/archive/2004/10/25/150117.aspx vb.net的位置:我觉得这似乎有点不对径,怎么可能fortron等这些老掉牙的语言这么高,竟然比VB.NET还高。
这是(MS SQL)如何实现相关文章功能(多关键字匹配)的改进版,参考了和 的建议之后,
解决方案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。