none
SQL SERVER 2005位运算效率问题请教 RRS feed

  • 问题

  • 假如我有一张用户表my_tb_Users,有三个字段分别是:

    1. [ID] [int] NOT NULL
    2. [UserName] [varchar](20) NOT NULL
    3. [Type] [int] NOT NULL

    现在有两个查询语句:

        1. SELECT * FROM my_tb_Users WHERE [Type] = 8
        2. SELECT * FROM my_tb_Users WHERE ([Type] & 8) > 0

    请问在相同情境下,这两条查询效率是否相同,如果不同,那差距大概有多大?

    2009年10月28日 4:45

答案

  • 你可以试试下面这种方法:
    一.my_tb_UserArticleCategories 表上的ID列,在设置值的时候有规律一些,譬如“财经新闻”的ID是100,他的子类就是101-199间的,“军事新闻”的ID是200,他的子类ID设置成201-299间,以此类推
    二.my_tb_UserArticles 表增加一个计算列ParentCategoryID:CategoryID/100(这样的话“财经新闻”和他的子类算出来都是1),然后你可以在这个计算列上增加一个索引,查询的时候where ParentCategoryID=1就表示所有属于财经新闻分类的新闻
    2009年10月28日 6:13
    版主
  • 单纯的  CategoryID IN (1, 2,3,4,5) , 并且 CategoryID 有索引, 那么效率不会低的

    如果你实在不放心, 或者说你 in 里面的值非常多, 你可以用表变量和临时表把 1, 2,3,4,5 做为记录值存放直接, 然后与正式做做 join
    2009年10月29日 4:33

全部回复

  • 楼主,你这两个语句的意义都不相同吧?
    SELECT * FROM my_tb_Users WHERE ([Type] & 8) > 0的where条件要改成异或才和查询1的语义相同:where ([type]^8)=0
    你可以在查询的时候加上下面设置,看下io和执行时间方面的差别;
    set statistics io on
    set statistics time on

    另外实际的执行计划上也还是有区别的,指标“估计行数”就不同,你可以验证下
    2009年10月28日 5:01
    版主
  • 非常感谢你的回复!
    其实我是想做一个新闻系统,新闻分类是多级的。

    新闻分类表如下:

    create table my_tb_UserArticleCategories (
       ID                  int                  not null,
       ParentID         int                  null,
       UserID            int                  not null,
       Name              nvarchar(50)   not null
    )

    新闻表如下:
    create table my_tb_UserArticles (
       ID                   int                    not null,
       CategoryID      int                    not null,
       UserID             int                    not null,
       Title                 nvarchar(100)   not null,
       Body                ntext                not null,
       Tags                 nvarchar(50)    not null,
       JoinTime           datetime          not null,
       UpdateTime       datetime         not null,
       Source              int                  not null,
       Status               int                  not null,
       Hits                   int                  not null
    )

    假如新闻分类表数据如下(ParentID = 0表示是顶级分类):

        ID   ParentID    UserID    Name   

    1. 0                             财经新闻
    2. 1                             宏观经济
    3. 1                             沪深股市
    4. 1                             美国股市
    5. 1                             香港股市
    6. 0                             军事新闻
    7. 0                             时政新闻
    8. 0                             科技新闻

    假如我现在要求获取所有属于财经新闻分类的新闻,那我该如何操作。
    按我现在的设计,大概只能使用这样的查询语句来实现了
    SELECT * FROM my_tb_UserArticles WHERE CategoryID IN (1, 2,3,4,5)

    这样做是不是效率偏低,是否有更好的方法实现?  

    2009年10月28日 5:46
  • 你可以试试下面这种方法:
    一.my_tb_UserArticleCategories 表上的ID列,在设置值的时候有规律一些,譬如“财经新闻”的ID是100,他的子类就是101-199间的,“军事新闻”的ID是200,他的子类ID设置成201-299间,以此类推
    二.my_tb_UserArticles 表增加一个计算列ParentCategoryID:CategoryID/100(这样的话“财经新闻”和他的子类算出来都是1),然后你可以在这个计算列上增加一个索引,查询的时候where ParentCategoryID=1就表示所有属于财经新闻分类的新闻
    2009年10月28日 6:13
    版主
  • 再次感谢您的精彩回复,谢谢!
    我先试验下!
    • 已编辑 卡车司机 2009年10月28日 6:55 有错别字
    2009年10月28日 6:26
  • 单纯的  CategoryID IN (1, 2,3,4,5) , 并且 CategoryID 有索引, 那么效率不会低的

    如果你实在不放心, 或者说你 in 里面的值非常多, 你可以用表变量和临时表把 1, 2,3,4,5 做为记录值存放直接, 然后与正式做做 join
    2009年10月29日 4:33