select count(*) from tab_log A INNER JOIN tab_tld_id B ON A.tld =B.ID where B.tld = 'cn'
explain select count(*) from tab_log where tld = (select id from tab_tld_id where tld = 'cn');这种语法上就有问题啊,除非你的 (select id from tab_tld_id where tld = 'cn');只返回一行记录。如果只返回一行,则主要是优化你的 tab_log 表上 tld 这一列上加上索引。
select count(*) from tab_log where tld = (select id from tab_tld_id where tld = 'cn') 耗时:2min53.67sec select count(*) from tab_log A INNER JOIN tab_tld_id B ON A.tld =B.ID where B.tld = 'cn' 耗时:2min51.50sec我用explain看了一下,两种方法都是全表扫描,没有用到索引,难道count(*)就注定不能用索引吗?
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 TABLE tab_tld_id(tld CHAR(10) NOT NULL,id TINYINT UNSIGNED NOT NULL,PRIMARY KEY(id)); tab_log的tld字段建立了索引,tab_tld_id的 tld字段建立了唯一索引。
select count(a.tld) from tab_log A INNER JOIN tab_tld_id B ON A.tld =B.ID where B.tld = 'cn'在tab_tld_id上建立(ID,tld)复合索引
是的,这个从你的语法格式中就已经确定了。 现在估计你的问题主要是在 select count(*) from tab_log where tld = 123; 直接把你(select id from tab_tld_id where tld = 'cn')的值代进去,看看时间是多少?另外从你的create table tab_log 语句上看不出来tld有索引存在。如果没有索引的话自然是个全表扫描。用 show index from tab_log; 看一下都有哪些索引。 然后再贴一下你的explain select count(*) from tab_log where tld = 123;
create index IX_tab_tld_id_main on tab_tld_id(tld,ID)create index IX_tab_log_main on tab_log(tld)执行上面语句后,再测试下效率看看 如果可以的话,把执行计划贴出来看看吧
+----+-------------+----------+------+---------------+------+---------+------+----------+----------- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra +----+-------------+----------+------+---------------+------+---------+------+----------+----------- | 1 | SIMPLE | tab_log | ALL | NULL | NULL | NULL | NULL | 167460001|Using where +----+-------------+----------+------+---------------+------+---------+------+----------+------------------
楼上再 show index 一下呢,很明显,似乎根本没有基于explain select count(*) from tab_log where tld = 123; 上的tld 的索引。
我检查过了,tld列上有索引,可是没有用,仍然是全表扫描,问题应该在于怎麽在语句中利用索引
有没有贴一下你的结果看一下。mysql> show index from t1; +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | t1 | 0 | PRIMARY | 1 | id | A | NULL | NULL | NULL | | BTREE | | +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 1 row in set (0.06 sec)
INNER JOIN tab_tld_id B
ON A.tld =B.ID
where B.tld = 'cn'
from tab_log
where tld = (select id from tab_tld_id where tld = 'cn');这种语法上就有问题啊,除非你的 (select id from tab_tld_id where tld = 'cn');只返回一行记录。如果只返回一行,则主要是优化你的 tab_log 表上 tld 这一列上加上索引。
耗时:2min53.67sec
select count(*) from tab_log A
INNER JOIN tab_tld_id B
ON A.tld =B.ID
where B.tld = 'cn'
耗时:2min51.50sec我用explain看了一下,两种方法都是全表扫描,没有用到索引,难道count(*)就注定不能用索引吗?
)CREATE TABLE tab_tld_id(tld CHAR(10) NOT NULL,id TINYINT UNSIGNED NOT NULL,PRIMARY KEY(id));
tab_log的tld字段建立了索引,tab_tld_id的 tld字段建立了唯一索引。
INNER JOIN tab_tld_id B
ON A.tld =B.ID
where B.tld = 'cn'在tab_tld_id上建立(ID,tld)复合索引
是的,这个从你的语法格式中就已经确定了。
现在估计你的问题主要是在
select count(*) from tab_log where tld = 123;
直接把你(select id from tab_tld_id where tld = 'cn')的值代进去,看看时间是多少?另外从你的create table tab_log 语句上看不出来tld有索引存在。如果没有索引的话自然是个全表扫描。用 show index from tab_log; 看一下都有哪些索引。
然后再贴一下你的explain select count(*) from tab_log where tld = 123;
如果可以的话,把执行计划贴出来看看吧
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
+----+-------------+----------+------+---------------+------+---------+------+----------+-----------
| 1 | SIMPLE | tab_log | ALL | NULL | NULL | NULL | NULL | 167460001|Using where
+----+-------------+----------+------+---------------+------+---------+------+----------+------------------
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| t1 | 0 | PRIMARY | 1 | id | A | NULL | NULL | NULL | | BTREE | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
1 row in set (0.06 sec)
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| tab_log | 0 | PRIMARY | 1 | id | A | NULL | NULL | NULL | | BTREE | |
| tab_log | 0 | PRIMARY | 2 | time | A | 167460001 | NULL | NULL | | BTREE | |
| tab_log | 1 | idx_ip | 1 | ip | A | 900322 | NULL | NULL | | BTREE | |
| tab_log | 1 | idx_mhtype | 1 | htype | A | 5 | NULL | NULL | | BTREE | |
| tab_log | 1 | idx_mtld | 1 | tld | A | 13 | NULL | NULL | | BTREE | |
| tab_log | 1 | idx_mqtype | 1 | qtype | A | 25 | NULL | NULL | | BTREE | |
| tab_log | 1 | idx_mflag | 1 | flag | A | 4 | NULL | NULL | | BTREE | |
+---------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
这个是结果。多谢!
照这样说的话,如果用位图索引会好一些?但是好像Mysql里没有位图索引,Oracle里有位图索引。