这样一个表: 
CREATE TABLE TEST( 
 MyYear int not null, 
 MyMonth  int not null,
 ID int not null ,
 ...
)因数据量大,经常要查询年月区间的数据, 例如 2000年1月 到2005年3月之间的数据
我这样用:SELECT * FROM TEST 
WHERE MyYear*12+MyMonth  >= (2000*12+1) AND MyYear*12+MyMonth  <= (2005*12+3)想问:能够为 MyYear*12+MyMonth 建立索引吗?或者怎样的 SQL 语句才能快点(避免表扫描)。

解决方案 »

  1.   

    select * 的话,肯定是要扫描的,除非lz做覆盖索引,全都带上。时间区间的数据,可以使用分区表来处理。
      

  2.   

    可以考加一个列整合year和month,为这个列加索引。
    否则,这个sql就得分拆开来写了.
      

  3.   

    WHERE (MyYear>= 2000 and MyYear<=2004) or (MyYear=2005 and MyMonth>=1 and  MyMonth <= 3)
      

  4.   

    我当年做银行系统的时候日期就是int类型,但是是20130109这样的8位,在这里创建聚集索引,速度还是可以接受的,而你这样拆分来存,不一定高效,毕竟一般都要带上年月,这样就要涉及两个字段。
      

  5.   


    扫描是因为select *?
    select *只是在过滤结束后,返回的记录集(可能只是全部记录里的很小一部分)的字段多一点而已吧
    扫描是过滤时,没有合适的索引,才不得不扫描,有索引就不会扫描(全部记录)了
      

  6.   

    看来对字段进行计算之后,索引就无效了。
    增加或改变字段意义,这个改动太多。不愿意这么做。查找年月区间时,如果要使用索引,那个逻辑挺复杂的。
    2000年5月到2005年3月 好象是这样吧:
    这是查询年份不同的:
       ( MyYear = 2000 AND MyMonth >= 5 ) OR
       ( MyYear = 2005 AND MyMonth <= 3 ) OR
       ( MyYear > 2000 AND MyYear  < 2005) //如果年份相邻,还要去掉该项
    这是查询年份相同的:2000年3-5月
       ( MyYear == 2000 AND MyMonth between 3 AND 5)
    还有只查整年的,或只查某月的,SQL 语句写起来一大串,我也不知道是否漏掉什么条件没。怎样写才通用些。
    此时应该是分别为年月建索引。
      

  7.   


    我的理解,有索引
    可以直接对索引区通过二分查找定位到符合条件的记录的索引项,再一次次根据符合条件的索引项跳到对应的记录的保存的位置,再取需要的字段(select *则取所有字段)
    不会扫描所有的表记录