小弟现在要做一个查询,存放主要信息的表中的数据量在一千万左右主要结构如下ID(LONG), CONTENT(VARCHAR), USERCODE(VARCHAR) , SUBMITTIME(DATETIME)主键自增   用户数据             用户编码          提交时间我现在要做的工作是写一个查询SQL查询一个用户在某段时间内提交的数据,当然,如果数量多的话必然是分页查询我的SQL 先去查询了表中的复合要求的记录,然后用这部分记录去和其他几个表关联,取得相关信息比如这样SELECT A.CONTENT, B,USERNAMEFROM (SELECT CONTENT , USERCODE, SUBMITTIME FROM 表 WHERE USERCODE = '' AND SUBMITTIME BETWEEN ‘时间1' AND '时间2')  A , USERINFO BWHERE A.USERCODE = B.USERCODE
表中除了主键字段有索引外,DBA给建的索引有 USERCODE字段建了一个不唯一非聚集的索引SUBMITTIME字段也建立的不唯一非聚集索引但是,问题来了,我如果不对提交时间进行过滤,只使用USERCODE字段做过滤,也就是查询出该用户的所有记录这个时候我发现比 查询该用户一个时间段的所有记录要快感觉很明显,前者需要不到1秒的时间,后者就可以感觉到明显的停顿,要等4-5秒的样子但是DBA不是给建立了两个索引吗?我去问DBA,他给我解释不清他给我查看了2005给做的执行计划,从执行计划上看,效果应该是反过来的但是事实上不是,最终DBA找到了一个认为说的过去的理由他说,是因为我选择的用户特殊,有可能这个用户数据的数据存储位置比较特殊,所以快了。但是我不认同这个观点,因为第一,他拿不出证据证明测试用户的数据存储位置特殊第二,我用5个测试用户测试这个SQL结果都是和执行计划给出的速度比相反,难道我这5个用户的数据都特殊?这个查询领导给布置的工作就是要查询效率高,不能让用户感觉长时间的等待众位高手谁指导指导我吧。

解决方案 »

  1.   

    你是不是可以From (这里面的东西)写成一个视图呢?
      

  2.   


    哥哥你好,我是不知道为什么两个索引反倒比一个索引慢而且 为什么执行计划里给的结果是和执行效果反过来的?还有就是,如果我查询的WHERE字句里有时间条件,SQLServer会给我自动做排序?按照你的回复,我猜测是因为,系统根据索引找到了用户代码符合条件的数据然后再从这堆数据中去过滤时间了?那时间字段的那个索引用到了吗?谢谢~
      

  3.   

    你虽然SUBMITTIME有建索引,但执行的时候不一定会用索引,还有其它因素在影响它,比如:这个时间段返回的数据量大不大等,你要看执行计划
      

  4.   

    请问 “查询该用户一个时间段的所有记录” 大概多少记录,
    是否都用到了  USERCODE,SUBMITTIME字段上不唯一非聚集的索引
      

  5.   

    试试这个:
    SELECT A.CONTENT, B,USERNAME from 表 a inner join userinfo b on a.usercode=b.cusecode
    where usercode='' and SUBMITTIME BETWEEN '时间1' AND '时间2'
      

  6.   

    SELECT A.CONTENT, B,USERNAME from 表 a inner join userinfo b on a.usercode=b.cusecode
    where a.usercode='' and a.SUBMITTIME BETWEEN '时间1' AND '时间2'
      

  7.   


    大哥,你给的SQL我考虑过这么写但是我是这样想的,两个表做关联,笛卡尔积是成数量级的增长的。尤其是A表千万级数据量,B表也小不了,也有几万条记录这样做的话,要从多大的一个笛卡尔积里查询数据啊?况且我要关联的码表除了用户表还有4个所以我用了我现在的写法我想的是,先从A表里取出复合条件的记录,然后用这个临时表去和其他表关联这样笛卡尔积就小了很多,一个用户也就大几百条记录。不知道我这么想是否正确啊~您说的方法,我现在就去试试谢谢啊~
      

  8.   

    试试把USERCODE、SUBMITTIME建立联合索引,而不是分别建立单一索引,看看性能呢?
      

  9.   

    --根据你的描述,你的表存在3个索引(设为PK_ID,ix_username,ix_submittime)
    --语句1
    SELECT CONTENT , USERCODE, SUBMITTIME FROM 表 WHERE USERCODE = ''
    --语句2
    SELECT CONTENT , USERCODE, SUBMITTIME FROM 表 WHERE USERCODE = '' AND SUBMITTIME BETWEEN ‘时间1' AND '时间2'你说语句1比2速度快得多。我认为原因只能是SQL SERVER优化引擎在执行语句2时,选择了错误的索引。这涉及到SQL SERVER对多个索引的选择问题。这个题目很大,在这里我不作具体分析。只提两个解决建议:
    1、更新该表的统计信息 
    UPDATE STATISTICS tb
    2、在语句2中加上索引提示.如
    SELECT CONTENT , USERCODE, SUBMITTIME FROM 表 with (index(索引名)) WHERE USERCODE = '' AND SUBMITTIME BETWEEN ‘时间1' AND '时间2' 
    --其中的索引名,可以选择语句1中SQL执行计划用的索引名。结贴,是一种美德
      

  10.   

    以上问题未细看,仅对执行计划相反提示如下:
    图形化的执行计划查看顺序是从左←右,从上↓下,
    而showplan_text不同级别分析是从下↑上,同级则是从上↓下分析。
      

  11.   


    大哥你放心,我好歹也在CSDN上潜水有几年了规矩还是懂滴
      

  12.   

    这两个条件一个是做“=”, 一个是“between and ”
    这样似乎只能用到一个索引,你需要强制使用速度好 的索引