表结构:
CREATE TABLE tab_log
(
id         INT UNSIGNED NOT NULL AUTO_INCREMENT,
time       TIME NOT NULL,
ip         BIGINT UNSIGNED NOT NULL,
domain     VARCHAR(1000) NOT NULL,
htype      TINYINT UNSIGNED NOT NULL,
tld        TINYINT UNSIGNED NOT NULL,
qtype      TINYINT UNSIGNED NOT NULL,
flag       TINYINT UNSIGNED NOT NULL,
PRIMARY KEY(id),
);
CREATE INDEX idx_dmn ON tab_log (domain);
CREATE INDEX idx_ip ON tab_log (ip);
CREATE INDEX idx_time ON tab_log (time);
由于htype、tld、qtype、flag 4 列的基数很小,所以没有建立索引。
SQL语句如下:
select domain,count(*) as COUNT from tab_log where tld = 0 group by domain order by COUNT desc;目的是查询每个域名的被查询次数,并按照次数降序排列。可是很慢,很久都不出结果,表中的记录不是很多,有17680001条。
请高人帮忙,怎样才能优化这条SQL语句,提高查询性能?期待

解决方案 »

  1.   

    select domain,count(*) as COUNT from tab_log where tld = 0 group by domain
    运行速度如何?
    有排序的语句运行是比较慢
      

  2.   

    先去掉排序
    select domain,count(domain) as COUNT from tab_log where tld = 0 group by domain
      

  3.   


    explain select domain,count(*) as COUNT from tab_log where tld = 0 group by domain order by COUNT desc;看一下情况。
      

  4.   

    +----+-------------+--------------+------+---------------+----------+---------+-------+----------+----------------------------------------------+
    | id | select_type | table        | type | possible_keys | key      | key_len | ref   | rows     | Extra                                        |
    +----+-------------+--------------+------+---------------+----------+---------+-------+----------+----------------------------------------------+
    |  1 | SIMPLE      | tbl_20090703 | ref  | idx_mtld      | idx_mtld | 1       | const | 10105316 | Using where; Using temporary; Using filesort | 
    +----+-------------+--------------+------+---------------+----------+---------+-------+----------+----------------------------------------------+
    这是explain后的结果,
    我在tld列还是加上了索引
      

  5.   

    idx_mtld 是什么索引?怎么没看到你在一楼提起?
      

  6.   

    建议加一个索引
    CREATE INDEX idx_dmn_tld ON tab_log (domain,tld);
      

  7.   

    是在tld列上建立的普通索引,一楼的时候还没加上。由于该列基数(势)很小,加不加影响不大。
      

  8.   

    如果tld 的势很小,则可以不建这个(domain,tld);索引试一下
    select domain,count(*) as COUNT 
    from tab_log FORCE  INDEX FOR  GROUP BY(idx_dmn) 
    where tld = 0 
    group by domain ;
    ORDER BY 没办法,这是个统计结果,没办法利用任何索引。
      

  9.   

    试了一下,现在还没有结果。Explain的结果是:
    +----+-------------+--------------+------+---------------+----------+---------+-------+----------+----------------------------------------------+ 
    | id | select_type | table        | type | possible_keys | key      | key_len | ref  | rows    | Extra                                        | 
    +----+-------------+--------------+------+---------------+----------+---------+-------+----------+----------------------------------------------+ 
    |  1 | SIMPLE      | tbl_20090703 | ALL  | NULL      | NULL | NULL| NULL| 17680001| Using where; Using temporary; Using filesort | 
    +----+-------------+--------------+------+---------------+----------+---------+-------+----------+----------------------------------------------+
      

  10.   

    什么KEY都没用上!。你EXPLAIN的是哪一句?
      

  11.   

    explain select domain,count(*) as COUNT 
    from tab_log FORCE  INDEX FOR  GROUP BY(idx_dmn) 
    where tld = 0 
    group by domain ;
    就是这一句。。
      

  12.   

    mysql> explain select domain,count(*) as COUNT
        -> from tab_log FORCE  INDEX FOR  GROUP BY(idx_dmn)
        -> where tld = 0
        -> group by domain ;
    +----+-------------+---------+------+---------------+----------+---------+-------+------+----------------------------------------------+
    | id | select_type | table   | type | possible_keys | key      | key_len | ref   | rows | Extra                                        |
    +----+-------------+---------+------+---------------+----------+---------+-------+------+----------------------------------------------+
    |  1 | SIMPLE      | tab_log | ref  | idx_mtld      | idx_mtld | 1       | const |    1 | Using where; Using temporary; Using filesort |
    +----+-------------+---------+------+---------------+----------+---------+-------+------+----------------------------------------------+
    1 row in set (0.00 sec)
      

  13.   

    tld列的idx_mtld势很小,等于8,我就把那个索引删掉了,所以explain的结果和您的不一样。问题是这对查询速度有很大的影响吗?
      

  14.   

    未必有很大的影响,因为基本上是做全表扫描。除非能有个(domain,tld);的索引
     (domain) 的索引只能加快一下group by, 或者 (tld)的索引只能先做个筛选,之后的合计还是会花时间。