读书人

帮忙优化个sql语句,该怎么处理

发布时间: 2012-03-23 12:06:21 作者: rapoo

帮忙优化个sql语句
场景大概如下,有BookInfo以及QueryPlan两张表,分别是表示书籍、我的定制。
我的定制的意思是,用户可以设置自己定制的方案,之后一进系统就显示该方案对应的书籍。

表结构大概如下:

BookInfo:BookID,BookName,BookTypeID(所属分类的ID),Author(作者),press(出版社)...
QueryPlan:UserID,Flag(标志该方案是否为默认方案,用户可以有多个方案),BookTypeID(数据类型大概是",a,b,fas,fre,"表示用户该定制方案是这四种书籍的分类),Author(作者),press(出版社)...大概就这么些字段。

我自己写的语句如下:

SQL code
select top 5 BookID,BookName,b.Author,PressTime,Thumbnail from dbo.BookInfo b where charindex(b.Booktypeid,(select BookTypeID from dbo.QueryPlan where UserID = 'sunyusheng' and Flag = 'true')) >0 or (charindex(author,(select author from dbo.QueryPlan where UserID = 'sunyusheng' and Flag = 'true')) > 0) or (charindex(press,(select press from dbo.QueryPlan where UserID = 'sunyusheng' and Flag = 'true')) > 0)


由于BookInfo表数据量是一百万以上的,执行以上语句差不多是30秒。用户接受不了。请各位高手们帮帮忙,怎么优化这个语句,也可以通过索引或者其他的办法,只要行得通就可以了。但是修改表结构的办法就不用了,项目是二期的,没得对表结构做修改。。

[解决办法]
SQL code
select top 5 BookID,BookName,b.Author,PressTime,Thumbnail from dbo.BookInfo b where  exists (select 1 from dbo.QueryPlan where UserID = 'sunyusheng' and Flag = 'true' and (charindex(b.Booktypeid,BookTypeID)>0 or charindex(b.author,author) or charindex(b.press,press)>0))
[解决办法]
主要的是charindex()在SQL Server 2000 & SQL Server 2005法用到索引,上百的BookInfo表,最好的解方法就是,考能用到合的索引。可以考下面方法:

SQL code
--1.在表BookInfo的Booktypeid author press字段建合索引--2. Booktypeid author press成列表形式 ,以便能使用到索引Declare @sql nvarchar(4000)if object_id('Tempdb..#') Is Not Null Drop Table #if object_id('Tempdb..#QueryPlan') Is Not Null Drop Table #QueryPlanCreate Table #QueryPlan(Detail nvarchar(50),DetailType smallint) /* 1.BookTypeID 2.author 3.press */Create clustered  Index IX_#QueryPlan On #QueryPlan (DetailType Asc)select author,BookTypeID,press Into # from dbo.QueryPlan where UserID = 'sunyusheng' and Flag = 'true'If Exists(Select 1 from # Where BookTypeID>'')Begin    Set @sql='Select 1,'''+Replace((Select BookTypeID From #),',',''' union All Select 1,''')+''''    insert into QueryPlan(DetailType,Detail) Exec (@sql)End If Exists(Select 1 from # Where author>'')Begin    Set @sql='Select 2,'''+Replace((Select author From #),',',''' union All Select 2,''')+''''    insert into QueryPlan(DetailType,Detail) Exec (@sql)End If Exists(Select 1 from # Where press>'')Begin    Set @sql='Select 3,'''+Replace((Select press From #),',',''' union All Select 3,''')+''''    insert into QueryPlan(DetailType,Detail) Exec (@sql)End --3修改查句,查看行,是否用到索引,整索引,就能提高查效率--3.aselect top 5 BookID,BookName,b.Author,PressTime,Thumbnail from dbo.BookInfo b Where Exists(Select 1                     From #                     Where (Detail=b.BookTypeID And DetailType=1) --BookTypeID                        Or (Detail=b.author And DetailType=2) --author                        Or (Detail=b.press And DetailType=3) --press                )--
[解决办法]
由于在booktypeid,author,press字段大量用到字符以及字符串,所以加索引也未必有效,如果你这个系统不是24小时全时工作的话,我建议可以新建一表,将你自己写的那个sql语句做成存储过程,每天12点将你的存储过程的结果保存到表里,然后将"我的定制"这个默认功能从这张表里取,这样就算用户很多,但是因为不会出现charindex这样的运算,还是能快很多的,charindex真的伤不起啊

读书人网 >SQL Server

热点推荐