我有条语句select count(UserId) from User where UserId in (2,3,4,20,5,7,8) ;
我用explain解释后发现查询type为index,后来仔细查看后发现问题出在in (2,3,4,20,5,7,8),in后面只能带5个参数,如果大于5个那么查询速度就会降低,请问有什么办法解决吗??怎么样才能让查询类型升到range级别啊??UserId是主键

解决方案 »

  1.   

    怎么样才能让查询类型升到range级别啊??
    用表保存2,3,4,20,5,7,8,比如ID,在此字段上建立索引,与工作表连接
      

  2.   

    UserId是主键啊 本身就有主键索引了。。你说的保存数据也不行啊 我其实用这句话是用来统计行数的,在自身的存储过程中调用的。。那样肯定不行的
      

  3.   

    比如LSB:
    ID
    2
    3
    4
    20
    5
    7
    8在ID字段上建立索引
    select * from tt a inner join lsb b on a.UserId=b.id
      

  4.   

    select count(UserId) from User where UserId =2
    union all
    select count(UserId) from User where UserId =2
    ......这样每条命令都是range了。
      

  5.   

    哎。。先谢谢大家了。。不过你们的办法都不行啊这个是在存储过程里的原句
    SELECT COUNT(UserId) INTO @RowCount FROM User where UserId in (2,3,4,20,5,7,8);
    我需要 @RowCount 这个值来统计返回的条数,做分页的。。
      

  6.   

    select count(*) from tt a inner join lsb b on a.UserId=b.id

    SELECT COUNT(UserId) INTO @RowCount FROM User where UserId in (2,3,4,20,5,7,8);
    等价
      

  7.   

    select count(*) from tt a inner join lsb b on a.UserId=b.id
    你写的是多表连接啊 ?? 和我的完全不是一个意思。。你告诉我的根本没用啊 怎么用 自连接啊??那返回的是全记录好不好,我不要返回全记录啊
      

  8.   

    那没辙了。WWWA的办法是建一个辅助表。你的结构定死了,那没法了。
      

  9.   

    SELECT COUNT(UserId) INTO @RowCount FROM User where UserId in (2,3,4,20,5,7,8);这个就是得到一个汇总和,你可以修改存储过程不??
    把2,3,4,20等当做一个个单独的等于查询,最后去再把值相加,得到总数。
      

  10.   

    再说一次
    select count(*) from tt a inner join lsb b on a.UserId=b.id

    SELECT COUNT(UserId) INTO @RowCount FROM User where UserId in (2,3,4,20,5,7,8);
    语句的另外一种 写法,只返回一个总数,可以将COUNT(*)->COUNT(UserId)
      

  11.   

    where UserId in (2,3,4,20,5,7,8)
    这个where其实是一个参数 是前台传入的值。。所以我根本不知道要传多少个进来 是不固定的,但是现在超过5个就肯定有问题。。没办法改。。
    至于wwwwa实在不好意思。。我没明白你的意思,select count(*) from tt a inner join lsb b on a.UserId=b.id
    lsb 是什么啊??
      

  12.   

    SELECT COUNT(UserId) INTO @RowCount FROM User where UserId in (2,3,4,20,5,7,8);没有什么好的办法。 不建议使用另外一个临时表,速度根本不会加快。这个问题本版精华中已经讨论过了。INDEX索引后,速度上应该不是大问题了。
      

  13.   

    哎 现在问题是如果用index查询,每次有人调用这个存储过程,慢查询记录就会增加一条。。
    他的方法我不是没有想过,不过每次都创建 效率是不高,查询到还可以改成这样就行了
    select * from User a join UserFriend b on a.UserId = b.UserId where b.UserId > 0;
      

  14.   

    你的查询语句到底是什么? 是这句吗?select count(UserId) from User where UserId in (2,3,4,20,5,7,8) ;
      

  15.   

    其实他是一个存储过程用来做分页设计的,前台传了一个wherecase,它的值一般就是where UserId in (2,3,4,20,5,7,8)这种类似的值,前面是SELECT COUNT(UserId) INTO @RowCount FROM User,用RowCount来统计返回的条数。
      

  16.   

    其实你不需要先取COUNT,你可以直接进行查询,然后通过 FOUND_ROWS() 得到总的记录条数。
      

  17.   

    楼主可以参考精华贴中的。http://topic.csdn.net/u/20090522/09/bb244d6e-528f-45f4-8829-dfa955c5ba82.html?43340
      

  18.   

    -- --------------------------------------------------------------------------------
    -- Routine DDL
    -- --------------------------------------------------------------------------------
    DELIMITER $$CREATE DEFINER=`root`@`` PROCEDURE `User_GetPaged`(
        _WhereClause VARCHAR(250),
        _OrderBy VARCHAR(250),
        _PageIndex INT,
        _PageSize INT,
        OUT _TotalCount INT
    )
    BEGIN
        
        SET @RowCount = 0;
        
        SET @SqlStr = 'SELECT COUNT(UserId) INTO @RowCount FROM User';
        IF _WhereClause IS NOT NULL AND _WhereClause <> '' THEN
            SET @SqlStr = CONCAT(@SqlStr, ' WHERE ', _WhereClause);
        END IF;
        
        PREPARE StmtTotalCount FROM @SqlStr;
        EXECUTE StmtTotalCount;
        DEALLOCATE PREPARE StmtTotalCount;
        SET _TotalCount = @RowCount;
        
        SET @SqlStr = 'SELECT UserId, Email, UserFirstName, UserLastName, Password, UserStatusId, CreateDate FROM User';
        IF _WhereClause IS NOT NULL AND _WhereClause <> '' THEN
            SET @SqlStr = CONCAT(@SqlStr, ' WHERE ', _WhereClause);
        ELSE
            SET @SqlStr = CONCAT(@SqlStr, ' WHERE UserId > 0 ');
        END IF;
        IF _OrderBy IS NOT NULL AND _OrderBy <> '' THEN
            SET @SqlStr = CONCAT(@SqlStr, ' ORDER BY ', _OrderBy);
        END IF;
        
        IF _PageIndex > 0 AND _PageSize > 0 THEN
            SET @LimitStart = (_PageIndex - 1) * _PageSize;
            SET @LimitEnd = _PageSize;
            SET @SqlStr = CONCAT(@SqlStr, ' LIMIT ', @LimitStart, ',', @LimitEnd);
        END IF;
        
        PREPARE StmtRecord FROM @SqlStr;
        EXECUTE StmtRecord;
        DEALLOCATE PREPARE StmtRecord;END$$
    我的储存过程是这样的
      

  19.   

    RowCount是个动态值,根据查询的UserId来改变的 所以你说获取全部行数 肯定不行的
      

  20.   

    FOUND_ROWS() 是符合条件的记录总数。 楼主不要急于下结论,看完精华贴再给出你的自己的想法。否则如果别人的建议你看也不看就否定,别人也没什么办法来帮助你了。
      

  21.   

    不好意思。。是我太急了。。这个问题我卡了很多天了。。不过这个函数怎么用啊 我用了后怎么返回不同的结果啊是不是先执行select count(UserId) from User where UserId in (1,2,3,4,5,6,28,30)然后再执行select FOUND_ROWS()??哪怎么一个返回5 一个返回1啊?
      

  22.   

    http://topic.csdn.net/u/20090522/09/bb244d6e-528f-45f4-8829-dfa955c5ba82.html?43340这个贴子看了吗?里面的例子很清楚了啊。
      

  23.   

    select UserId from User where UserId in (1,2,3,4,5,6,28,30);

    select FOUND_ROWS();这样。
      

  24.   

    恩 我知道怎么做了 谢谢各位的帮忙了~~ 是我自己太不仔细了 没看到ACMAIN_CHM大大写的一些细节问题。。 真的很谢谢各位!!